深刻理解HashMap

HashMap和HashTable的區別java

HashMap的底層原理?算法

HashMap是一個存儲Key-Value鍵值對的集合,每個鍵值對也叫Entry,Key-Value是做爲一個總體出現的,這些鍵值對分散的存儲在一個數組中,這個數組就叫HashMap。對HashMap來講,最經常使用的方法是Put和Get。HashMap數組的每個元素不僅是一個Entry對象,也是一個鏈表的頭結點。數組

一、Put的原理(根據Key值計算HashCode,根據HashCode獲得Entry的插入位置index)安全

好比調用HashMap.put("apple",0)插入一個Key爲Apple的元素,這時候要肯定插入的位置index。併發

index=Hash("apple"),假設計算的index是2,結果以下:app

可是HashMap的長度是有限的,當插入的Entry愈來愈多時,會發生index衝突的狀況,例以下面:函數

這時候能夠用鏈表解決,HashMap數組中每個元素不只僅是一個Entry對象,也是一個鏈表的頭結點。每個Entry對象經過Next指針指向它的下一個Entry節點,當新來的Entry映射到衝突數組位置時,只須要插入對應的鏈表便可。插入時採用「頭插入」高併發

HashMap的底層實現仍是數組,數組中的每一個元素是鏈表。優化

 

這裏咱們再來複習put的流程:當咱們想一個HashMap中添加一對key-value時,系統首先會計算key的hash值,而後根據hash值確認在table中存儲的位置。該位置沒有元素,則直接插入。不然迭代該處元素鏈表並依此比較其key的hash值。若是兩個hash值相等且key值相等(e.hash == hash && ((k = e.key) == key || key.equals(k))),則用新的Entry的value覆蓋原來節點的value。若是兩個hash值相等但key值不等 ,則將該節點插入該鏈表的鏈頭。具體的實現過程見addEntry方法,ui

二、Get的原理(根據Key值獲得index)

把輸入的Key作一次Hash映射,獲得對應的index,

index=Hash("apple")

因爲剛纔所說的Hash衝突,同一個位置可能匹配到多個Entry對象,這時候就要順着鏈表的頭結點,依次向下查找。第一次查找到的節點是Entry6.Entry6的Key是banana,不是要找的結果,第二次查找的節點是Entry1,Entry1對應的Key是Apple,是要找的結果。

 

你知道HashMap的get()方法的工做原理嗎?

HashMap默認的長度是多少?爲何這樣規定?

HashMap的初始長度爲16,每次拓展或者手動初始化時,必須爲2的冪。

初始長度選擇16是爲了服務於從Key到index的Hash算法,咱們要獲得一個儘可能均勻分佈的Hash函數,利用Key的HashCode作取模運算,(index=HashCode(Key)%Length),可是取模運算的效率很低,因此HashMap發明者採用位運算的方式(採用按位與運算實現取模),如何進行位運算,有以下的公式:

index=HashCode(Key)%(Length-1)

能夠看出:Hash算法最終獲得的結果,取決於HashCode的後幾位。

這樣作的好處是:當Length是16或者其餘2 的冪,Length-1的每一位都是1,index的結果等於HashCode的後面幾位,只要輸入的HashCode是分佈均勻的,Hash算法計算的index也是均勻的

對於HashMap的table而言,數據分佈須要均勻(最好每項都只有一個元素,這樣就能夠直接找到),不能太緊也不能太鬆,太緊會致使查詢速度慢,太鬆則浪費空間。使用index=HashCode(Key)%(Length-1)就是爲了讓table中的元素儘可能均勻。

因此說當length = 2^n時,不一樣的hash值發生碰撞的機率比較小,這樣就會使得數據在table數組中分佈較均勻,查詢速度也較快。

(若是Length-1=0011,則index某些值出現的概率大,某些值永遠不可能出現)

高併發狀況下,爲何HashMap會出現死鎖?

獲得

在Java8中,HashMap的結構有什麼優化?

在java8中,若是hash相同的Key的數量大於8時,會用紅黑樹代替鏈表。

高併發下的HashMap

一些須要注意的點

  • HashMap有負載因子和極限容量,默認負載因子爲0.75
  • 兩個線程同時嘗試擴容HashMap時,可能會將鏈表造成環形鏈表,全部的next都不爲空,進入死循環。(HashMap是線程不安全的
  • 兩個線程同時進行put時可能會形成一個線程數據缺失。
相關文章
相關標籤/搜索