更新Java HashMap键

前端之家收集整理的这篇文章主要介绍了更新Java HashMap键前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我只是想知道,如果HashMap的关键字是可变的,那么会发生什么,下面的测试程序会演示,当我们都等于和hashCode方法返回时,我无法理解
true和相同的值,为什么hashmap.containsKey返回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;
    }
}

这个输出

true
false 6 6 true

解决方法

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.

基本上,不要在地图中使用可变对象作为键,你将被烧毁

要推断,因为文档可能不清楚,我相信这里的相关点是以影响equals的方式进行更改,而且您似乎假设每次调用包含的equals(Object)时都会调用该对象.文档没有说,这个措辞意味着它们可能被允许缓存计算.

看看source,似乎是因为你的hashCode返回一个不同的值(现在是5,现在是6),它可能是根据实现细节在不同的桶中查找的.

猜你在找的Java相关文章