这是一种学术观点,但如果我不明白为什么如 Effective Java 和许多 SO questions 等书籍推荐这样做,我觉得我不完全理解哈希码。
认为:
public sealed class Point
{
private readonly int x;
private readonly int y;
//constructor ommited
//equals ommited
public override int GetHashcode()
{
int hash = 17; //why should the initial value be non-zero?
unchecked
{
hash = hash * 31 + x; //do not tell me why I should use primes - that is not the question
hash = hash * 31 + y;
return hash;
}
}
}
现在,据推测,初始值的原因是它减少了其中一个组件为零的碰撞。
我正在努力寻找任何有帮助的例子。
这是一个碰撞的例子,但是有一个初始值没有任何可能性。
x y Hash Without initial value Hash With initial value
0 31 31 16368
1 0 31 16368
理想情况下,我正在寻找一个初始值防止碰撞的具体示例。
我关于为什么初始值永远不会有所作为的理论
//Given a prime p, initial value i, fields a,b,c, calculate hash h
h = i;
h = h*p + a;
h = h*p + b;
h = h*p + c;
所以:
h = ((i*p + a)*p + b)*p + c
= (ipp + ap + b )*p + c
= ippp + app + bp + c
因此,初始值i
将通过产生一个常数值以相同的方式影响所有哈希码,在本例中为i*p
3。