HashMap擴容的背景及原理

/**
 * 初始化容量
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
 * 負載因子/閾值
 * The load factor used when none specified in constructor
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;
背景:
    HashMap存儲會存在hash衝突(碰撞的狀況),經過查看源碼能夠發現,當一個HashMap被建立時,他的初始化容量大小爲16,咱們這裏稱做
hash桶,默認有16個桶,默認負載因子/閾值爲0.75,當往map裏put數據時會針對key值key.hashCode()的hashcode值進行hash(Object
key) 運算,經過index = hash & (tab.length – 1)方法計算得出數據將要存放目標桶,當存在不一樣的key值通過hash計算以後獲得了同
一個目標桶,則這個桶裏將要存儲兩份數據,在存儲上,這個桶裏這兩份數據會以鏈表的形式存儲,當數據存儲過多時,碰撞的概率會增長,單個hash
桶中的鏈表會變長,當下次經過get方法查詢數據時,一樣會通過hash獲得數據存儲的目標桶可是這時這個桶裏存放了多條數據以鏈表的形式存儲,
這時候須要從鏈表裏找出我須要的數據則須要遍歷鏈表,鏈表過長時,查詢速度較慢,爲了下降hash衝突的出現機率,保證查詢的效率,擴容的概念
更值得關注。
HashMap擴容的條件:
   一、HashMap中的數據達到閾值。
   二、出現hash碰撞的狀況。
擴容機制:
    由初始化hash桶數量16和閾值0.75爲例,當map中的數據達到16*0.75=12時,此時map中的數據已經達到了hashmap擴容機制的閾值,當再
次插入第13個數據時hashmp將自動擴容(前面十二個數據中有出現hash衝突的前提下),擴容的hash桶大小以2的n次方增長,16擴容以後爲32。
擴容的缺點:
   在開發過程當中,若是hashmap自動擴容後,而咱們又不會再往hashmap中put數據,這時擴容的意義可能就沒那麼大,甚至是無效擴容,因此在開
發時能夠本身預估hashmap所須要的容量,經過指定hashmap的初始化容量和閾值來避免無效擴容。
總結:
   HashMap的擴容、人爲的設置HashMap容量和閾值限制自動擴容都是在進行時間和空間上的權衡,即內存和效率上的選擇,若是但願查詢快點,
則下降負載因子,增長HashMap初始容量,下降key值hash碰撞的概率。

複製代碼
相關文章
相關標籤/搜索