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

时间:2013-01-18 10:50:50

标签: java hashmap

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

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

3 个答案:

答案 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中找到密钥(及其值)。