不可变对象作为哈希集合中的关键
我已经读过,最好将不可变对象作为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
不需要重新计算哈希码。 它计算一次然后它可以缓存该值。