当向hashMap添加键值对时,为什么Java会生成hashMap';什么是哈希代码更改?

当向hashMap添加键值对时,为什么Java会生成hashMap';什么是哈希代码更改?,java,hash,hashmap,hashcode,hashset,Java,Hash,Hashmap,Hashcode,Hashset,如果查看hashMap中java的hashCode方法,您会发现: public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; } 那里的高兰蒂人可能会发生碰撞。还有其他Map实现,包括和,它们不显示您描述的

如果查看hashMap中java的hashCode方法,您会发现:

public int hashCode() {
    int h = 0;
    Iterator<Entry<K,V>> i = entrySet().iterator();
    while (i.hasNext())
        h += i.next().hashCode();
    return h;
}
那里的高兰蒂人可能会发生碰撞。还有其他
Map
实现,包括和,它们不显示您描述的行为。在
LinkedHashMap
的情况下,Javadoc(部分)将其描述为
Map
接口的哈希表和链表实现,具有可预测的迭代顺序

为什么Java允许这样的行为

因为根据键的
equals()
实现,键应该是不变的。如果对键进行变异,从而影响通过其
equals()
方法进行的比较,则映射的行为未指定

这正是当您更改
HashMap
而它是
HashSet
的一个元素时所做的,因为
HashSet
实际上是由
HashMap
支持的

这是一个节选的:

注意:如果将可变对象用作贴图键,则必须非常小心。如果对象是贴图中的关键点时,对象的值以影响相等比较的方式更改,则不会指定贴图的行为。这项禁令的一个特例是,不允许地图本身包含密钥。虽然允许映射将自身包含为一个值,但还是要特别小心:equals和hashCode方法在这样的映射上不再得到很好的定义


如果我是你,我不会使用可变映射作为依赖于其元素不可变性的结构的键。

你想知道为什么,还是想知道如何解决这个问题?我想知道为什么HashMap的哈希代码依赖于其存储的数据。
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

public class Main {

    public static void main(String[] args) {

        HashSet<HashMap<Integer, String>> set = new HashSet<>();
        HashMap<Integer, String> b = new HashMap<>();
        System.out.println("adding hashcode: " + b.hashCode() + "to set");
        set.add(b);
        b.put(8, "arsenal");
        for(HashMap<Integer, String> map: set){
            Iterator it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry pair = (Map.Entry)it.next();
                System.out.println(pair.getKey() + " = " + pair.getValue());
            }
        }
        System.out.println("Finding b: " + set.contains(b));
        System.out.println(b.hashCode());

        set.add(b);

        for(HashMap<Integer, String> map: set){
            Iterator it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry pair = (Map.Entry)it.next();
                System.out.println(pair.getKey() + " = " + pair.getValue());
            }
        }

    }
}