HashMap 的幾個要點
阿新 • • 發佈:2019-02-05
1、HashMap的資料結構是”連結串列雜湊”,具體如下:
2、兩個引數:initialCapacity 、loadFactor
其中initialCapacity 決定了上圖所示的table的被初始建立的長度,當然這還不是初始長度,初始長度是大於initialCapacity 的最小的2的n次方,(為什麼不能直接用initialCapacity作為初始長度呢?待會會分析到2的n次方的table長度的好處,一是可以優化取模的計算,如何優化待會分析。二是雜湊均勻,其實這就是取模的好處了)。 而loadFactor*初始長度就是hashmap的擴容閾值,至於為什麼要擴容,那是因為要避免上圖的連結串列過長。3、連結串列存的是什麼?
這裡有個問題,就是為什麼Entry為什麼不只存有key值就好,還要多存key的hash值呢? 先看一下hashmap的put方法的原始碼:
通過原始碼我們可以清晰看到HashMap儲存資料的過程為:首先判斷key是否為null,若為null,則直接呼叫putForNullKey方法。若不為空則先計算key的hash值,然後根據hash值搜尋在table陣列中的索引位置,如果table陣列在該位置處有元素,則通過比較是否存在相同的key,若存在則覆蓋原來key的value,否則將該元素儲存在鏈頭(最先儲存的元素放在鏈尾)。若table在該處沒有元素,則直接儲存。
其實put時,會呼叫key的兩個方法,一個是hashCode(),一個是equals(),兩個物件相等的條件是hashCode和equal相等,或者是hashcode()和key1==key2,其中hash()是將key轉化成一種新的表達,有key1!=key2 可以推出 hash(key1)!=hash(key2)。但是這對於數值型這個規律是滿足現實看法的。但是對於物件不一樣了,如我新建了兩個學生物件,存了相同的學生資訊,現實中這兩個物件是對應同一個學生的,所以這兩個物件應該是相等的,但是由於物件的地址空間不同,所以hashCode(key1)!=hashCode(key2),而且物件的key1.equal(key2)預設是key1==key2,所以程式判斷這兩個程式判斷這兩個物件是不相等的,這是有悖於實際的。
參考連結: http://mp.weixin.qq.com/s?__biz=MjM5MTM0NjQ2MQ==&mid=2650140213&idx=2&sn=3a921452cc4616caa12e70665c0f599d&chksm=beb7b44789c03d51f47624c493630059a4011a3f67aa9b6634decdcf5f403c565093187a067e&mpshare=1&scene=1&srcid=0225QS1R6PNzn7koY1cC6F0b#rd