【发布时间】:2017-08-31 08:54:22
【问题描述】:
在我的项目中,我使用 HashMap 来存储一些数据,最近我发现当我改变 HashMap 的键时,可能会出现一些意想不到的错误结果。例如:
HashMap<ArrayList,Integer> a = new HashMap<>();
ArrayList list1 = new ArrayList<>();
a.put(list1, 1);
System.out.println(a.containsKey(new ArrayList<>())); // true
list1.add(5);
ArrayList list2 = new ArrayList<>();
list2.add(5);
System.out.println(a.containsKey(list2)); // false
注意a.keySet().iterator().next().hashCode() == list2.hashCode() 和a.keySet().iterator().next().equals(list2) 都是真的。
我不明白为什么会这样,指的是两个对象相等并且具有相同的哈希码这一事实。有谁知道这是什么原因,以及是否有任何其他类似的结构允许密钥的突变?谢谢。
【问题讨论】:
-
不要使用可变值作为 hashmap 键。我以为它在 HashMap 的文档中某处说,但我现在找不到它。
-
我知道我不应该(关于我展示的示例)但我无法理解原因(对象相等并且具有相同的哈希码)并且我正在寻找类似的结构这允许。
-
"...是否有任何其他类似的结构允许键的突变?" - 密钥(至少构成密钥的部分)永远不会是可变的,因为这会妨碍它们的使用。把它想象成一把现实世界的钥匙:如果你改变你的钥匙,它就不会再打开锁了。如果你换了锁,你需要一把新钥匙。