不可变对象作为哈希集合中的关键

我已经读过,最好将不可变对象作为HashMap中的键,因为它会缓存生成的哈希码。

为什么不可变对象会默认缓存哈希代码? 将不可变对象作为键是真正的优势吗?

这不是真正的主要原因(并且不可变对象可能不会缓存其哈希码)。

真正的(潜在的)问题是,如果密钥的哈希码在哈希映射中发生变化,则对map.containsKey(modifiedKey)的调用可能会返回false,尽管密钥仍然在地图中。

访问它然后迭代的唯一方法。

请注意,实际结果可能会因地图实施而异。

见下面一个人为的例子。 输出是:


1
{1 = ABC}

意思是地图认为关键不再存在,但它实际上仍然存在。

 public class Test2 { public static void main(String[] args) { Map map = new HashMap<> (); Mutable m = new Mutable(); map.put(m, "abc"); mi = 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不需要重新计算哈希码。 它计算一次然后它可以缓存该值。