1. 程式人生 > >HashMap 容量為2次冪的原因

HashMap 容量為2次冪的原因

我們都知道 hashmap 的底層是一個數組加連結串列的結構,當向其中新增一個元素的時候,需要根據key的hash值,去確定其在陣列中的具體位置。
在這裡插入圖片描述
看原始碼,我們可以發現,確定陣列位置的實現是 i=(n-1)& hash,其中 n 代表陣列的長度,即map的容量。

當n為2的冪次方時,(n-1)& hash 的值是均勻分佈的,我們假設n=16,hash從0開始遞增:

hash (n-1)& hash 結果
0 1111 & 0 0
1 1111 & 1 1
2 1111 & 10 2
3 1111 & 11 3
4 1111 & 100 4
5 1111 & 101 5
…… …… ……
16 1111 & 10000 0
17 1111 & 10001 1
18 1111 & 10010 2

當n不為2的冪次方時,(n-1)& hash 的值不是是均勻分佈的,我們假設n=15,hash從0開始遞增:

hash (n-1)& hash 結果
0 1110 & 0 0
1 1110 & 1 0
2 1110 & 10 2
3 1110 & 11 2
4 1110 & 100 4
5 1110 & 101 4
…… …… ……
16 1110 & 10000 0
17 1110 & 10001 0
18 1110 & 10010 2

由上面可以看出,當我們根據key的hash確定其在陣列的位置時,如果n為2的冪次方,可以保證資料的均勻插入,如果n不是2的冪次方,可能陣列的一些位置永遠不會插入資料,浪費陣列的空間,加大hash衝突。
另一方面,一般我們可能會想通過 % 求餘來確定位置,這樣也可以,只不過效能不如 & 運算。而且當n是2的冪次方時:hash & (length - 1) == hash % length

因此,HashMap 容量為2次冪的原因,就是為了資料的的均勻分佈,減少hash衝突,畢竟hash衝突越大,代表陣列中一個鏈的長度越大,這樣的話會降低hashmap的效能。