检索地图中的对象

时间:2012-12-01 17:16:12

标签: java map hashcode

我正在尝试在更改其实例变量时将对象检索为Map中的键。就我而言,当我在Map结构中搜索一个关键对象时,它应该在hashCode方法返回与最初相同的值时出现。但是,基于以下代码,我无法通过方法get()检索变量权重的值来检索对象:

public class Car  implements Comparable<Car> {

 int weight;
 String name;

 public Car(int w, String n) {
    weight=w;
    name=n;
 }

public boolean equals(Object o){
    if(o instanceof Car){
        Car d = (Car)o;
        return ((d.name.equals(name)) && (d.weight==weight));
    }
    return false;

}

public int hashCode(){
    return weight/2 + 17;
}

public String toString(){
    return "I am " +name+ " with weight: "+weight;
}


public int compareTo(Car d){
    if(this.weight>d.weight)
        return 1;
    else if(this.weight<d.weight)
        return -1;
    else
        return this.name.compareTo(d.name);
}

}


public static void main(String[] args) {
    Car d1 = new Car(107, "a");
    Car d2 = new Car(110, "b");
    Car d3 = new Car(110, "c");
    Car d4 = new Car(107, "a");

    Map<Car, Integer> m = new HashMap<Car, Integer>();
    m.put(d1, 1);
    m.put(d2, 2);
    m.put(d3, 3);
    m.put(d4, 16);

    System.out.println(m.get(d1).toString());
    d1.weight = 34;
    System.out.println(m.get(new Car(34, "a")));

    for(Map.Entry<Car, Integer> me : m.entrySet())
        System.out.println(me.getKey().toString() + " value: " +me.getValue());

}

输出结果为:

16

null

I am a with weight: 34 16

I am c with weight: 110 3

I am b with weight: 110 2

但是,如果我不改变权重值(省略行:d1.weight = 34;),仅使用代码行:

System.out.println(m.get(new Car(107, "a")));

输出是:

16

16

I am a with weight: 107 value: 16

I am c with weight: 110 value: 3

I am b with weight: 110 value: 2

它实际上找到了对象。它是以两种方式达到预期的输出,还是在第一个版本中也找到并检索了对象?

2 个答案:

答案 0 :(得分:6)

将可变对象作为键存储在哈希表中时应该非常小心。在对象插入上仅对哈希码计算一次。如果您稍后以影响其哈希代码的方式更改对象,则很可能无法找到该对象。

您需要删除对象并在进行此类更改时重新插入。

答案 1 :(得分:0)

System.out.println(m.get(new Car(34, "a")));

您的地图在此处返回null,因为它不包含具有哈希码34的密钥对象。

然而

System.out.println(m.get(new Car(107, "a")));

你的地图确实会返回一个对象,因为它确实包含一个带有哈希码70的密钥对象。