为什么要向hashCode()添加一个常量? [英] Why would one add a constant to hashCode()?
问题描述
我是Java的新手,最近我了解了 hashCode()
.在关于Java hashCode()的维基百科文章上,有以下 hashCode()
方法:
I'm new to Java, and I've recently learned about hashCode()
. On the wikipedia article about Java hashCode(), there is the following example of a hashCode()
method:
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而不是 hashCode()
上加上17 * 31 * 13的效果,这不会改变两个hashCode()值是否相等.
I understand that multiplying by 31 and 13 decreases the chance of collision, but I don't see why hash
is initialized to 1 rather than to employeeId
. In the end this simply has the effect of adding 17*31*13 to the hashCode()
, which is not going to change whether two hashCode() values are equal or not.
Bloch的"Effective Java(第二版)"在第9项(第47和48页)中有一个非常相似的示例,但是他对这个可加常数的解释对我来说还是很神秘的.
Bloch's "Effective Java (Second Edition)" has a very similar example in Item 9 (pages 47 and 48), but his explanation of this additive constant is quite mysterious to me.
This question was marked as a duplicate of the question Why does Java's hashCode() in String use 31 as a multiplier? That question is not the same: it is asking whether there is any reason to prefer the number 31 to any other number in the formula for the hashCode()
of a String
. My question is why it is the case that in many examples of hashCode()
which I have found online there is a single constant added to the hashCode()
of all objects.
实际上,这里的 String
的 hashCode()
示例是相关的,因为在该示例中没有添加常量.如果在我上面给出的示例中添加17 * 31 * 13起作用,为什么在计算 String
的 hashCode()
时不添加这样的常量?
In fact, the example of hashCode()
of a String
is relevant here, because in that example there is no constant added. If adding 17*31*13 has any effect in the example I gave above, why not add such a constant when computing hashCode()
of a String
?
推荐答案
以非零值开头在哈希码溢出或%非2的幂的情况下在概念上有帮助,这导致更多的位是不同的比较值,与之相比,溢出那些没有.
Starting with non zero value helps notionally when the hashCode overflows or is % by a non power of two which results in more bits being different comparing values which overflow compared to those which don't.
小常量不如大常量有效,但可以使用更少的字节并更快.例如.* 31更快,但可能不如* 109.
Small constants are not as effective as larger ones but can use less bytes and be faster. E.g. * 31 is faster but might not be as effective as * 109.
其区别取决于您的用例.
The difference it make depends on your use case.
注意:使用数字选择存储区后,即使确保您具有唯一的hashCode也不能确保没有冲突.
Note: even ensuring you have unique hashCodes doesn't ensure you have no collisions after the number has been used to select a bucket.
这篇关于为什么要向hashCode()添加一个常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!