我已经读过最好将不可变对象作为 HashMap 中的键,因为它会缓存生成的哈希码。
不可变对象如何默认缓存哈希码?将不可变对象作为键是真正的优势吗?
这并不是真正的主要原因(并且不可变对象可能不会缓存其哈希码)。
真正的(潜在的)问题是,如果键的哈希码在哈希映射中发生更改,则调用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);
}
}
}
这与缓存无关hashCode()
(不可变对象仍然可以动态计算它)。这与结果的稳定性有关hashCode()
。对于可变对象,hashCode()
可能依赖于可能更改的值,如果发生这种情况,您将无法再在HashMap
.
不可变对象永远不会改变。这意味着在HashMap
使用此键查找对象时不需要重新计算哈希码。它计算一次,然后可以缓存该值。