2016-03-15 133 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'。 –