2016-03-15 131 views
3

知道要获得两个对象的散列码,通常会对其各自的散列码进行异或运算。我想检查Tuple如何处理Item1 == Item2的情况。这是我在源代码中发现:Tuple's GetHashCode hack

internal static int CombineHashCodes(int h1, int h2) { 
     return (((h1 << 5) + h1)^h2); 
    } 

我认为这是为了避免所有相等的对象相同的hashCode,因为x^x = 0。为什么h1 << 5虽然?有没有一个原因,它是专门为5?难道只是1?请帮助我理解这一点。

+1

很多方法来写一个散列函数,它比普通的XOR更好,还是非常快的。这是伯恩斯坦的散列,又名djb2,减去种子。乘以33并不是任意的,在[this Q + A]中进行了说明(http://stackoverflow.com/questions/1579721/why-are-5381-and-33-so-important-in-the-djb2-algorithm) 。 –

+0

@HansPassant这是迄今为止我的问题的最佳答案,谢谢! – DevNewb

回答

3

((h1 << 5) + h1)相当于h1 * 33333 * 11
Java在某些哈希中使用31,因为它是素数,而h1 * 31(h1 << 5) - h,它几乎相同,但没有在总和的情况下可能发生的额外溢出。

+0

你也可以在这里阅读一些答案https://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier 例如,这一个是安静的信息http://stackoverflow.com/a/300111/2577420(常量31,33,37,39和41产生的碰撞不多) –

+1

'h1 << 5'实际上是'h1 * 32' – taffer

+1

@taffer这意味着在再次加上'h1'后,变成'* 33'或减去后变成'* 31'。 –