我是 Java 新手,最近了解了hashCode()
. On 关于 Java hashCode() 的维基百科文章 https://en.wikipedia.org/wiki/Java_hashCode(),有以下示例hashCode()
方法:
public class Employee {
int employeeId;
String name;
Department dept;
// other methods would be in here
@Override
public int hashCode() {
int hash = 1;
hash = hash * 17 + employeeId;
hash = hash * 31 + name.hashCode();
hash = hash * 13 + (dept == null ? 0 : dept.hashCode());
return hash;
}
}
我知道乘以 31 和 13 会减少碰撞的机会,但我不明白为什么hash
被初始化为 1 而不是employeeId
。最后,这只是将 17*31*13 添加到hashCode()
,这不会改变两个 hashCode() 值是否相等。
Bloch 的《Effective Java(第二版)》第 9 条(第 47 和 48 页)中有一个非常相似的例子,但他对这个加法常数的解释对我来说相当神秘。
编辑:此问题被标记为问题的重复项为什么Java的String中的hashCode()使用31作为乘数? https://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier这个问题是不一样的:它问是否有任何理由更喜欢数字 31 而不是公式中的任何其他数字hashCode()
of a String
。我的问题是为什么在许多例子中hashCode()
我在网上发现有一个常量添加到hashCode()
所有对象。
事实上,这个例子hashCode()
of a String
在这里相关,因为在那个例子中没有添加常数。如果在我上面给出的例子中添加 17*31*13 有任何效果,为什么不在计算时添加这样一个常数hashCode()
of a String
?
当 hashCode 溢出或者是 2 的非幂时,从非零值开始理论上会有所帮助,这会导致更多位是不同的比较值,溢出的值与未溢出的值相比。
小常数不如大常数有效,但可以使用更少的字节并且速度更快。例如。 * 31 更快,但可能不如 * 109 有效。
它所产生的差异取决于您的用例。
注意:即使确保您拥有唯一的 hashCodes,也不能确保在使用该数字选择存储桶后不会发生冲突。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)