问题描述
我只是想知道,如果 HashMap
的键是可变的会发生什么,下面的测试程序证明了这一点,我无法理解 equals 和 hashCode
方法何时返回true 和相同的值,为什么 hashmap.containsKey
返回 false
.
I was just wondering, what would happen if key of a HashMap
is mutable, test program below demonstrate that and I am unable to understand when both equals and hashCode
methods returns
true and same value, why does hashmap.containsKey
return false
.
public class MutableKeyHashMap {
public static void main(String []a){
HashMap<Mutable, String> map = new HashMap<Mutable, String>();
Mutable m1 = new Mutable(5);
map.put(m1, "m1");
Mutable m2 = new Mutable(5);
System.out.println(map.containsKey(m2));
m2.setA(6);
m1.setA(6);
Mutable m3 = map.keySet().iterator().next();
System.out.println(map.containsKey(m2)+" "+m3.hashCode()+" "+m2.hashCode()+" "+m3.equals(m2));
}
}
class Mutable {
int a;
public Mutable(int a) {
this.a = a;
}
@Override
public boolean equals(Object obj) {
Mutable m = (Mutable) obj;
return m.a == this.a ? true : false;
}
@Override
public int hashCode(){
return a;
}
public void setA(int a) {
this.a = a;
}
public int getA() {
return a;
}
}
这是输出:
真假 6 6 真
推荐答案
javadoc 解释它
注意:如果将可变对象用作映射键,则必须非常小心.如果对象的值以影响等于比较的方式更改,而对象是映射中的键,则不会指定映射的行为.
Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.
基本上,不要在 Map 中使用可变对象作为键,否则会被烧毁
Basically, don't use mutable objects as keys in a Map, you're going to get burnt
推断,因为文档可能看起来不清楚,我相信这里的相关点是以影响 equals 的方式更改",并且您似乎假设每次调用 contains 时都会调用 equals(Object).文档没有这么说,措辞暗示它们可能被允许缓存计算.
To extrapolate, because the docs may not appear clear, I believe the pertinent point here is `changed in a manner that affects equals', and you seem to be assuming that equals(Object) is called each time contains is invoked. The docs don't say that, the wording implies they may be allowed to cache computations.
查看source,似乎是因为您的hashCode 返回一个不同的值(以前是 5,现在是 6),可能是根据实现细节在不同的存储桶中查找它.
Looking at the source, it seems that because your hashCode returns a different value (was 5, now 6), it's possible that it's being looked up in a different bucket based on implementation details.
这篇关于更新 Java HashMap 键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!