在Java中,HashMap
的設計使其底層採用了陣列+連結串列/紅黑樹的形式來儲存元素。其中,陣列的長度(即table長度)為什麼要設定為2的n次方(2^n),有幾個關鍵原因:
-
雜湊分佈均勻性:2^n的陣列長度有助於雜湊函式更均勻地分佈鍵值對。當使用高質量的雜湊函式時,這種長度可以減少衝突的機率,從而提高
HashMap
的效能。因為在理想情況下,我們希望每個桶(陣列的一個元素)的元素數量儘可能接近平均值,減少查詢、插入和刪除操作的時間複雜度。 -
位運算效率:在確定元素儲存位置時,
HashMap
使用的是雜湊值與陣列長度減一的結果進行位與操作(即hash & (length-1)
)。如果陣列的長度是2的n次方,那麼length-1
的二進位制表示將是全部為1的數字,這樣可以確保雜湊值的所有位都參與到了計算中,同時也使得計算過程非常高效(位運算比乘除法和取模運算要快得多)。 -
動態擴容簡便性:當
HashMap
中的元素數量超過了負載因子和當前容量的乘積時,就需要進行擴容(通常是翻倍,即容量乘以2)。由於原始容量已經是2的冪,翻倍後的容量仍然是2的冪,這使得在擴容時可以很容易地重新計算每個元素的儲存位置。並且,由於長度是2的冪,一些鍵值對在擴容時可能直接保持在原位置或者移動到長度為新容量的位置,這個過程利用了位運算的特性,簡化了重新雜湊的計算。
這些設計選擇共同作用於HashMap
的效能最佳化,確保了其在各種使用場景下的高效和穩定。