更新Java HashMap密钥 [英] Updating Java HashMap key

查看:101
本文介绍了更新Java HashMap密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道,如果 HashMap 的关键字是可变的,会发生什么情况,下面的测试程序证明了这一点,并且我无法理解何时equals和 hashCode 方法返回
true和相同的值,为什么 hashmap.containsKey 返回 false < code $。

  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;
返回m.a == this.a?真假;
}

@Override
public int hashCode(){
return a;
}

public void setA(int a){

this.a = a;
}

public int getA(){
return a;


$ / code $ / pre

这个输出:


true
false 6 6 true


解决方案

javadoc 解释它


注意:如果可变对象用作映射键,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是地图中的键,则不会指定地图的行为。


基本上,不要在Map中使用可变对象作为键,否则将会被烧毁



为了推断,因为文档可能不会看起来很清楚,我相信这里的相关观点是以一种影响平等的方式改变的,而且你似乎认为每次包含被调用时都会调用equals(Object)。文档中并没有说,措辞意味着他们可能被允许缓存计算。



查看 source ,似乎是因为你的hashCode返回一个不同的值(是5,现在是6),可能它正在被查看根据实施细节在不同的存储桶中提供。

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;
    }
} 

This the output :

true false 6 6 true

解决方案

The javadoc explains it

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.

Basically, don't use mutable objects as keys in a Map, you're going to get burnt

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.

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密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆