【问题标题】:search perticular object element from user defined hashmap key in java从java中用户定义的hashmap键中搜索特定的对象元素
【发布时间】:2015-11-25 14:44:50
【问题描述】:

例如,我想在 java hashmap 中的用户定义键中搜索元素

在这个例子中可以像 hm.containsKey(new Price("Banana", 20)), 但在本例中,我想按价格或商品等特定数据成员进行搜索。

public class MyObjectKeySearch {
 
public static void main(String a[]){
         
        HashMap<Price, String> hm = new HashMap<Price, String>();
        hm.put(new Price("Banana", 20), "Banana");
        hm.put(new Price("Apple", 40), "Apple");
        hm.put(new Price("Orange", 30), "Orange");
        printMap(hm);
        Price key = new Price("Banana", 20);
        System.out.println("Does key available? "+hm.containsKey(key));
    }
     
    public static void printMap(HashMap<Price, String> map){
         
        Set<Price> keys = map.keySet();
        for(Price p:keys){
            System.out.println(p+"==>"+map.get(p));
        }
    }
}
 
class Price{
     
    private String item;
    private int price;
     
    public Price(String itm, int pr){
        this.item = itm;
        this.price = pr;
    }
     
    public int hashCode(){
        System.out.println("In hashcode");
        int hashcode = 0;
        hashcode = price*20;
        hashcode += item.hashCode();
        return hashcode;
    }
     
    public boolean equals(Object obj){
        System.out.println("In equals");
        if (obj instanceof Price) {
            Price pp = (Price) obj;
            return (pp.item.equals(this.item) && pp.price == this.price);
        } else {
            return false;
        }
    }
     
    public String getItem() {
        return item;
    }
    public void setItem(String item) {
        this.item = item;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
     
    public String toString(){
        return "item: "+item+"  price: "+price;
    }
}

【问题讨论】:

  • 请发布您的代码
  • 我已经在这个例子中发布了我的代码,我可以按新价格(项目,价格)搜索,但我只想按项目或价格搜索

标签: java collections hashmap


【解决方案1】:

是的:

hm.containsKey(new Price("Banana", 20))

是可能的,并且会按照您期望的方式运行。

否: 您不能基于不涉及遍历 HashMap 的键集的关键对象的成员进行任何包含检查。 containsKey(paramKey) 如果在 key.hashCode() 标识的相应“哈希桶”中有一个等于 paramKey 的键,则返回 true。 hashCode() 的值掩盖了成员值。 您可以使用更复杂的数据结构,例如嵌套的 HashMap:

HashMap<String, HashMap<Integer, String>> hm;

您在哪里使用 item 字符串作为外部 Map 中的键,使用 price 整数作为内部 Map 中的键。然后你可以像这样查询:

(hm.containsKey("Banana") && hm.get("Banana").containsKey(20))

这将比迭代大量 Price 对象更有效。但是,这仍然不允许您在不迭代外部键集的情况下有效地查询具有特定价格(整数)的所有内部条目。不过,您可以相应地反转内部和外部键类型:

HashMap<Integer, HashMap<String, String>> hm;

当然,您可以创建自己的类来封装两者的功能:

/* Provides constant time (O(1)) Price lookup by item and price */
class PriceMap {
    private HashMap<String, Set<Price>> stringMap;
    private HashMap<Integer, Set<Price>> intMap;

    public PriceMap() {
        stringMap = new HashMap<String, Set<Price>>();
        intMap = new HashMap<Integer, Set<Price>>();
    }

    public void add(Price price) {
        String item = price.getItem()
        if (!stringMap.containsKey(item))
            stringMap.put(item, new HashSet<Price>());
        stringMap.get(item).add(Price);
        int price = price.getPrice()
        if (!intMap.containsKey(price))
            intMap.put(price, new HashSet<Price>());
        intMap.get(price).add(Price);
    }

    public Set<Price> prices(int price) {
        return intMap.containsKey(price) ? intMap.get(price) : new HashSet<Price>(); 
    }

    public boolean containsKey(int price) {
        return intMap.containsKey(price); 
    }

    public Set<Price> prices(String item) {
        return stringMap.containsKey(item) ? stringMap.get(item) : new HashSet<Price>(); 
    }

    public boolean containsKey(String item) {
        return stringMap.containsKey(item); 
    }

}

【讨论】:

  • 谢谢,你能给我一些来源或链接,以便更详细地解释
  • 在这个线程中,有一些解释:stackoverflow.com/questions/5056708/…,否则一般java API文档:docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
  • 我不想使用嵌套哈希图,我只是想解释一下您在回答中提到“NO 部分”
  • HashMap 中的键由它们的 hashCode() 函数查找,该函数返回一个隐藏键成员的 int 值。因此,查找具有特定成员值的键需要您查看每个键并观察该成员。我将编辑我的答案以指定...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 2018-09-10
  • 2021-12-12
相关资源
最近更新 更多