我們知道,n代表的是table的長度length,之前一再強調,表table的長度需要取2的整數次冪,就是為了這里等價這里進行取模運算時的方便——取模運算轉化成位運算公式:a%(2^n) 等價於 a&(2^n-1),而&操作比%操作具有更高的效率。
當length=2n時,(length - 1)正好相當於一個"低位掩碼","與"操作的結果就是散列值的高位全部歸零,只保留低位,用來做數組下標訪問:
可以看到,當我們的length為16的時候,哈希碼(字符串“abcabcabcabcabc”的key對應的哈希碼)對(16-1)與操作,對於多個key生成的hashCode,只要哈希碼的后4位為0,不論不論高位怎么變化,最終的結果均為0。也就是說,如果支取后四位(低位)的話,這個時候產生"碰撞"的幾率就非常大(當然&運算中產生碰撞的原因很多,這里只是舉個例子)。為了解決低位與操作碰撞的問題,於是便有了第二步中高16位異或低16位的“擾動函數”。
右移16位,自己的高半區和低半區異或,就是為了混合原始哈希碼的高位和低位,以此來加大低位隨機性。
可以看到: 擾動函數優化前:1954974080 % 16 = 1954974080 & (16 - 1) = 0 擾動函數優化后:1955003654 % 16 = 1955003654 & (16 - 1) = 6 很顯然,減少了碰撞的幾率。