1. HashMap在什么條件下擴容
判斷HashMap的數組Size大小如果超過loadFactor*capacity,就要擴容。
相關的類屬性:
-
capacity:當前數組容量,始終保持 2^n,可以擴容,擴容后數組大小為當前的 2 倍。
-
loadFactor:負載因子,默認為 0.75
loadFactor加載因子是控制數組存放數據的疏密程度,loadFactor越趨近於1,那么 數組中存放的數據(entry)也就越多,也就越密,也就是會讓鏈表的長度增加,loadFactor越小,也就是趨近於0,數組中存放的數據(entry)也就越少,也就越稀疏。
loadFactor太大導致查找元素效率低,太小導致數組的利用率低,存放的數據會很分散。loadFactor的默認值為0.75f是官方給出的一個比較好的臨界值
給定的默認容量為 16,負載因子為 0.75。Map 在使用過程中不斷的往里面存放數據,當數量達到了 16 * 0.75 = 12 就需要將當前 16 的容量進行擴容,而擴容這個過程涉及到 rehash、復制數據等操作,所以非常消耗性能。
-
threshold:擴容的閾值
threshold = capacity * loadFactor,當Size>=threshold的時候,那么就要對數組擴增了。
2. HashMap 的長度為什么是2的冪次方
為了能讓 HashMap 存取高效,盡量減少碰撞,把數據分配均勻,利用擾動函數hash方法對key進行處理得到Hash值。Hash 值的范圍值-2147483648到2147483647,前后加起來大概40億的映射空間,只要哈希函數映射得比較均勻松散,一般應用是很難出現碰撞的。但問題是一個40億長度的數組,內存是放不下的。所以這個散列值是不能直接拿來用的。用之前還要先做對數組的長度取模運算,得到的余數才能用來要存放的位置也就是對應的數組下標。這個數組下標的計算方法是“ (n - 1) & hash”。(n代表數組長度)
取余(%)操作中如果除數是2的冪次則等價於與其除數減一的與(&)操作(也就是說 hash%length==hash&(length-1)的前提是:length 是2的 n 次方),且采用二進制位操作 &,相對於%能夠提高運算效率,這就解釋了 HashMap 的長度為什么是2的冪次方。