HashMap的底層數據結構和源碼分析

HashMap 的數據結構

HashMap實際上是一個“鏈表散列”的數據結構,即數組和鏈表的結合體。數組是用來確定桶的位置,利用元素的key的hash值對數組長度取模得到。鏈表是用來解決hash衝突問題,當出現hash值一樣的情形,就在數組上的對應位置形成一條鏈表。

從上圖中可以看出,HashMap 底層就是一個數組結構,數組中的每一項又是一個鏈表。當新建一個 HashMap 的時候,就會初始化一個數組。也就是說在構造函數中,其創建了一個 Entry 的數組,Entry 是一個 static class,其中包含了 key 和 value,也就是鍵值對,另外還包含了一個 next 的 Entry 指針。我們可以總結出:Entry 就是數組中的元素,每個 Entry 其實就是一個 key-value 對,它持有一個指向下一個元素的引用,這就構成了鏈表。

當我們往 HashMap 中 put 元素的時候,先根據 key 的 hashCode 重新計算 hash 值,根據 hash 值得到這個元素在數組中的位置(即下標),如果數組該位置上已經存放有其他元素了,那麼在這個位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上。

hash衝突

就是鍵(key)經過hash函數得到的結果作爲地址去存放當前的鍵值對(key-value)(這個是hashmap的存值方式),但是卻發現該地址已經有人先來了,一山不容二虎,就會產生衝突。這個衝突就是hash衝突了。

一句話說就是:如果兩個不同對象的hashCode相同,這種現象稱爲hash衝突。

(1)兩個對象相等,hashcode一定相等
(2)兩個對象不等,hashcode不一定不等
(3)hashcode相等,兩個對象不一定相等
(4)hashcode不等,兩個對象一定不等

簡單地說,HashMap 在底層將 key-value 當成一個整體進行處理,這個整體就是一個 Entry 對象。HashMap 底層採用一個 Entry[] 數組來保存所有的 key-value 對,當需要存儲一個 Entry 對象時,會根據 hash 算法來決定其在數組中的存儲位置,在根據 equals 方法決定其在該數組位置上的鏈表中的存儲位置;當需要取出一個Entry 時,也會根據 hash 算法找到其在數組中的存儲位置,再根據 equals 方法從該位置上的鏈表中取出該Entry。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章