簡述 HashMap 擴容機制


HashMap基礎

【注意】以下內容只是針對 JDK1.8

HashMap繼承了AbstractMap類,實現了Map,Cloneable,Serializable接口。

其使用 hash 算法來決定元素的存儲,hash 表包含如下屬性。

  • 容量(capacity):hash 表數組的大小,默認為16;
  • 初始化容量(initial capacity):創建 hash 表時指定的初始容量;
  • 尺寸(size):當前 hash 表中記錄的數量;
  • 負載(load):負載等於 “ size / capacity ”。負載為 0 時,表示空的 hash 表。輕負載的 hash 表具有沖突少、適宜插入和查詢的特點。(但太小的話,又會增加占用的內存開銷)。
  • 負載因子(load factor):決定 hash 表的最大填滿程度,范圍是 0~1,默認為 0.75 。

當 hash 表的負載達到了指定的 “負載因子” 值時,hash 表就會加倍擴容,並將原有的對象重新分配,放入新的表中,這稱為 rehashing 。rehashing 過程很復雜,而已非常消耗性能,所以指定一個合適的 “負載因子” 值很重要。

當 size / capacity > 負載因子,即 size(當前記錄數) > 負載因子 * capacity(容量) 時,hash 會擴容。

HashMap的容量,默認是16

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

HashMap的加載因子,默認是0.75

/**
 * The load factor used when none specified in constructor.
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

當HashMap中元素數超過 容量 * 加載因子 時,HashMap會進行擴容。

擴容多大?

HashMap 擴容是為當前容量 * 2,也就是成倍擴容。

【問題1】為什么每次擴容的倍數是2,而不是1.5或者2.5 ?

理論上,擴容倍數用多少都行,1.5, 2.5 ,3.5都可以的,都能實現HashMap。

實際上,HashMap選用了2倍,是為了做一個優化。

因為計算哈希值的時候是使用取模運算,而HashMap的開發者想要優化下這個取模運算的速度,那么他就需要把HashMap內部的數組長度固定為 2^n 的長度了,也就是說HashMap里面的數組的長度,始終都是2的n次冪。為了實現這個效果,它的擴容因子很自然就是2倍了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM