我已经读过,最好将不可变对象作为HashMap中的键,因为它会缓存生成的哈希码。
为什么不可变对象如何使用默认值缓存哈希代码?将不可变对象作为键是真正的优势吗?
答案 0 :(得分:4)
这不是真正的主要原因(并且不可变对象可能不会缓存其哈希码)。
实际(潜在)问题是,如果密钥的哈希码在哈希映射中发生更改,则对map.containsKey(modifiedKey)
的调用可能会返回false,尽管该密钥仍在映射中。
访问它然后迭代的唯一方法。
请注意,实际结果可能会因地图实施而异。
见下面一个人为的例子。输出是:
假
1
{1 = ABC}
意思是地图认为密钥不再存在,但它实际上仍然存在。
public class Test2 {
public static void main(String[] args) {
Map<Mutable, String> map = new HashMap<> ();
Mutable m = new Mutable();
map.put(m, "abc");
m.i = 1;
System.out.println(map.containsKey(m));
System.out.println(map.size());
System.out.println(map);
}
public static class Mutable {
int i = 0;
@Override
public int hashCode() {
return i;
}
public String toString() {
return String.valueOf(i);
}
}
}
答案 1 :(得分:1)
不可变对象永远不会改变。这意味着HashMap
在使用此键查找对象时不需要重新计算哈希码。它计算一次,然后它可以缓存该值。
答案 2 :(得分:1)
这与hashCode()
的缓存无关(不可变对象仍然可以在运行中计算它)。它与hashCode()
结果的稳定性有关。对于可变对象,hashCode()
可能依赖于可能发生变化的值,如果发生这种情况,您将无法再在HashMap
中找到密钥(及其值)。