为什么哈希图中的不可变对象如此有效?
2022-09-01 04:34:37
所以我读了关于HashMap的文章。有人指出:
“不可变性还允许缓存不同键的哈希码,这使得整个检索过程非常快,并建议Java Collection API提供的String和各种包装类(例如)是非常好的键。
Integer
HashMap
我不太明白...为什么?
所以我读了关于HashMap的文章。有人指出:
“不可变性还允许缓存不同键的哈希码,这使得整个检索过程非常快,并建议Java Collection API提供的String和各种包装类(例如)是非常好的键。
Integer
HashMap
我不太明白...为什么?
String#hashCode
:
private int hash;
...
public int hashCode() {
int h = hash;
if (h == 0 && count > 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
由于内容永远不会改变,因此该类的创建者选择在计算一次哈希后缓存哈希。这样,就不会浪费时间重新计算相同的值。String
引用链接的博客文章:
具有适当等于 () 和哈希码 () 实现的最终对象将充当完美的 Java HashMap 键,并通过减少冲突来提高 Java hashMap 的性能。
我看不出两者如何,并且与哈希冲突有任何关系。这句话引起了我对文章可信度的怀疑。它似乎是教条式的Java“智慧”的集合。final
equals()
不可变性还允许缓存不同键的哈希码,这使得整个检索过程非常快,并建议String和各种包装类(例如Java Collection API提供的整数)是非常好的HashMap键。
我看到这句话有两种可能的解释,这两种解释都是错误的:
HashMap
缓存不可变对象的哈希代码。这是不正确的。地图无法确定对象是否“不可变”。因此,如果我们真的疯了,并且实际上决定使用a作为a的键,并使哈希值依赖于内容,而不是列表的标识,我们可以决定在每次修改时使缓存的哈希值无效,从而将哈希计算的次数限制为对列表的修改次数。List
HashMap