漫画:什么是HashMap
轉(zhuǎn)載自?玻璃貓 程序員小灰
眾所周知,HashMap是一個用于存儲Key-Value鍵值對的集合,每一個鍵值對也叫做Entry。這些個鍵值對(Entry)分散存儲在一個數(shù)組當(dāng)中,這個數(shù)組就是HashMap的主干。
HashMap數(shù)組每一個元素的初始值都是Null。
對于HashMap,我們最常使用的是兩個方法:Get?和?Put。
1.Put方法的原理
調(diào)用Put方法的時候發(fā)生了什么呢?
比如調(diào)用 hashMap.put("apple", 0) ,插入一個Key為“apple"的元素。這時候我們需要利用一個哈希函數(shù)來確定Entry的插入位置(index):
index =? Hash(“apple”)
假定最后計算出的index是2,那么結(jié)果如下:
但是,因為HashMap的長度是有限的,當(dāng)插入的Entry越來越多時,再完美的Hash函數(shù)也難免會出現(xiàn)index沖突的情況。比如下面這樣:
這時候該怎么辦呢?我們可以利用鏈表來解決。
HashMap數(shù)組的每一個元素不止是一個Entry對象,也是一個鏈表的頭節(jié)點。每一個Entry對象通過Next指針指向它的下一個Entry節(jié)點。當(dāng)新來的Entry映射到?jīng)_突的數(shù)組位置時,只需要插入到對應(yīng)的鏈表即可:
需要注意的是,新來的Entry節(jié)點插入鏈表時,使用的是“頭插法”。至于為什么不插入鏈表尾部,后面會有解釋。
2.Get方法的原理
使用Get方法根據(jù)Key來查找Value的時候,發(fā)生了什么呢?
首先會把輸入的Key做一次Hash映射,得到對應(yīng)的index:
index =? Hash(“apple”)
由于剛才所說的Hash沖突,同一個位置有可能匹配到多個Entry,這時候就需要順著對應(yīng)鏈表的頭節(jié)點,一個一個向下來查找。假設(shè)我們要查找的Key是“apple”:
第一步,我們查看的是頭節(jié)點Entry6,Entry6的Key是banana,顯然不是我們要找的結(jié)果。
第二步,我們查看的是Next節(jié)點Entry1,Entry1的Key是apple,正是我們要找的結(jié)果。
之所以把Entry6放在頭節(jié)點,是因為HashMap的發(fā)明者認為,后插入的Entry被查找的可能性更大。
————————————
之前說過,從Key映射到HashMap數(shù)組的對應(yīng)位置,會用到一個Hash函數(shù):
index =? Hash(“apple”)
如何實現(xiàn)一個盡量均勻分布的Hash函數(shù)呢?我們通過利用Key的HashCode值來做某種運算。
index =? HashCode(Key) % Length ?
如何進行位運算呢?有如下的公式(Length是HashMap的長度):
index =? HashCode(Key) &? (Length?- 1)?
下面我們以值為“book”的Key來演示整個過程:
1.計算book的hashcode,結(jié)果為十進制的3029737,二進制的101110001110101110 1001。
2.假定HashMap長度是默認的16,計算Length-1的結(jié)果為十進制的15,二進制的1111。
3.把以上兩個結(jié)果做與運算,101110001110101110 1001 &?1111 = 1001,十進制是9,所以 index=9。
可以說,Hash算法最終得到的index結(jié)果,完全取決于Key的Hashcode值的最后幾位。
假設(shè)HashMap的長度是10,重復(fù)剛才的運算步驟:
單獨看這個結(jié)果,表面上并沒有問題。我們再來嘗試一個新的HashCode??1011100011101011101011?:
讓我們再換一個HashCode?101110001110101110?1111?試試? :
是的,雖然HashCode的倒數(shù)第二第三位從0變成了1,但是運算的結(jié)果都是1001。也就是說,當(dāng)HashMap長度為10的時候,有些index結(jié)果的出現(xiàn)幾率會更大,而有些index結(jié)果永遠不會出現(xiàn)(比如0111)!
這樣,顯然不符合Hash算法均勻分布的原則。
反觀長度16或者其他2的冪,Length-1的值是所有二進制位全為1,這種情況下,index的結(jié)果等同于HashCode后幾位的值。只要輸入的HashCode本身分布均勻,Hash算法的結(jié)果就是均勻的。
—————END—————
總結(jié)
以上是生活随笔為你收集整理的漫画:什么是HashMap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 良苦用心和用心良苦有什么区别 良苦用心和
- 下一篇: 漫画:高并发下的HashMap