HashMap中為什么數(shù)組的長(zhǎng)度為2的冪次方

Java中HashCode算法詳解

Java中的集合,比如HashMap/HashSet/HashTable在實(shí)現(xiàn)上都用到了hashCode算法,用來計(jì)算元素在數(shù)組中的位置。hashCode是Object類中的一個(gè)方法,所以,所有的Java類都有這個(gè)方法,只是一些類對(duì)這個(gè)方法進(jìn)行了覆寫,下面以String類的實(shí)現(xiàn)為例進(jìn)行說明:

public int hashCode() {

????int h =hash;

? ? if (h ==0 &&value.length >0) {

????????char val[] =value;

? ? ? ? for (int i =0; i <?value.length; i++) {

????????h =31 * h + val[i];

? ? ? ? }

????????hash = h;

? ? }

????return h;

}

其實(shí)這個(gè)算法的實(shí)現(xiàn)很簡(jiǎn)單,以“hangzhou”這個(gè)字符串為例,計(jì)算過程如下:

第一步:int ‘h’

第二步:31 * (第一步結(jié)果) + int ‘a(chǎn)’

第三步:31 * (第二部結(jié)果) + int ‘n’

第四步:31 * (第三步結(jié)果) + int ‘g’

第五步:31 * (第四步結(jié)果) + int ‘z’

第六步:31 * (第五步結(jié)果) + int ‘h’

第七步:31 * (第六步結(jié)果) + int ‘o’

第八步: 31 * (第七步結(jié)果) + int ‘u’

可以得到“hangzhou”的hashcode為4740586。

為什么HashMap中的&位必須位奇數(shù)(length-1)

從key映射到HashMap數(shù)組的對(duì)應(yīng)位置需要一個(gè)Hash函數(shù):

index = Hash("hangzhou")

如何實(shí)現(xiàn)一個(gè)盡量分布均勻的hash函數(shù)呢?我們使用key的hashcode做某種運(yùn)算:

index = hashCode("hangzhou") & (Length - 1) 其中,Length為HashMap的長(zhǎng)度,下面來演示整個(gè)過程:

1、“hangzhou”的hashcode為4740586,二進(jìn)制表示為100 1000 0101 0101 1110 1010

2、假定HashMap的長(zhǎng)度為默認(rèn)的16,則Length - 1為15,也就是二進(jìn)制的1111

3、把以上兩個(gè)結(jié)果做與運(yùn)算,得到的結(jié)果為1010,也就是index為10

可以說,Hash算法最終得到的index結(jié)果完全取決于hashCode的最后幾位。

假設(shè),HashMap的長(zhǎng)度為10,則Length - 1為9,也就是二進(jìn)制的1001,通過Hash算法得到的最終index為8,當(dāng)只有一個(gè)元素的時(shí)候這沒問題。但是我們?cè)賮碓囈粋€(gè)hashCode:100 1000 0101 0101 1110 1110時(shí),通過Hash算法得到的最終的index也是8,另外還有100 1000 0101 0101 1110 1000得到的index也是8。也就是說,即使我們把倒數(shù)第二、三位的0、1變換,得到的index仍舊是8,說明有些index結(jié)果出現(xiàn)的幾率變大??!而有些index結(jié)果永遠(yuǎn)不會(huì)出現(xiàn),比如二進(jìn)制0000.

這樣,顯然不符合Hash算法均勻分布的要求。

反觀,長(zhǎng)度16或其他2的冪次方,Length - 1的值的二進(jìn)制所有的位均為1,這種情況下,Index的結(jié)果等于hashCode的最后幾位。只要輸入的hashCode本身符合均勻分布,Hash算法的結(jié)果就是均勻的。

一句話,HashMap的長(zhǎng)度為2的冪次方的原因是為了減少Hash碰撞,盡量使Hash算法的結(jié)果均勻分布。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容