0

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

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

4

3 回答 3

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);
        }
   }
}
于 2013-01-18T10:52:20.753 回答
1

这与缓存无关hashCode()(不可变对象仍然可以动态计算它)。这与结果的稳定性有关hashCode()。对于可变对象,hashCode()可能依赖于可能更改的值,如果发生这种情况,您将无法再在HashMap.

于 2013-01-18T10:54:27.530 回答
1

不可变对象永远不会改变。这意味着在HashMap使用此键查找对象时不需要重新计算哈希码。它计算一次,然后可以缓存该值。

于 2013-01-18T10:52:48.377 回答