HashMap 底層分析

以下基于 JDK1.7 分析。

image

如圖所示隶症,HashMap 底層是基于數(shù)組和鏈表實現(xiàn)的龙屉。其中有兩個重要的參數(shù):

  • 容量
  • 負載因子

容量的默認大小是 16呐粘,負載因子是 0.75,當(dāng) HashMapsize > 16*0.75 時就會發(fā)生擴容(容量和負載因子都可以自由調(diào)整)转捕。

put 方法

首先會將傳入的 Key 做 hash 運算計算出 hashcode,然后根據(jù)數(shù)組長度取模計算出在數(shù)組中的 index 下標作岖。

由于在計算中位運算比取模運算效率高的多,所以 HashMap 規(guī)定數(shù)組的長度為 2^n 五芝。這樣用 2^n - 1 做位運算與取模效果一致痘儡,并且效率還要高出許多。

由于數(shù)組的長度有限枢步,所以難免會出現(xiàn)不同的 Key 通過運算得到的 index 相同沉删,這種情況可以利用鏈表來解決,HashMap 會在 table[index]處形成鏈表醉途,采用頭插法將數(shù)據(jù)插入到鏈表中矾瑰。

get 方法

get 和 put 類似,也是將傳入的 Key 計算出 index 隘擎,如果該位置上是一個鏈表就需要遍歷整個鏈表殴穴,通過 key.equals(k) 來找到對應(yīng)的元素。

遍歷方式

 Iterator<Map.Entry<String, Integer>> entryIterator = map.entrySet().iterator();
        while (entryIterator.hasNext()) {
            Map.Entry<String, Integer> next = entryIterator.next();
            System.out.println("key=" + next.getKey() + " value=" + next.getValue());
        }
Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            System.out.println("key=" + key + " value=" + map.get(key));

        }
map.forEach((key,value)->{
    System.out.println("key=" + key + " value=" + value);
});

強烈建議使用第一種 EntrySet 進行遍歷嵌屎。

第一種可以把 key value 同時取出推正,第二種還得需要通過 key 取一次 value,效率較低, 第三種需要 JDK1.8 以上宝惰,通過外層遍歷 table植榕,內(nèi)層遍歷鏈表或紅黑樹。

notice

在并發(fā)環(huán)境下使用 HashMap 容易出現(xiàn)死循環(huán)尼夺。

并發(fā)場景發(fā)生擴容尊残,調(diào)用 resize() 方法里的 rehash() 時,容易出現(xiàn)環(huán)形鏈表淤堵。這樣當(dāng)獲取一個不存在的 key時寝衫,計算出的 index 正好是環(huán)形鏈表的下標時就會出現(xiàn)死循環(huán)。

image

所以 HashMap 只能在單線程中使用拐邪,并且盡量的預(yù)設(shè)容量慰毅,盡可能的減少擴容。

JDK1.8 中對 HashMap 進行了優(yōu)化: 當(dāng) hash 碰撞之后寫入鏈表的長度超過了閾值(默認為8)扎阶,鏈表將會轉(zhuǎn)換為紅黑樹汹胃。

假設(shè) hash 沖突非常嚴重婶芭,一個數(shù)組后面接了很長的鏈表,此時重新的時間復(fù)雜度就是 O(n) 着饥。

如果是紅黑樹犀农,時間復(fù)雜度就是 O(logn)

大大提高了查詢效率宰掉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呵哨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子轨奄,更是在濱河造成了極大的恐慌孟害,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戚绕,死亡現(xiàn)場離奇詭異纹坐,居然都是意外死亡枝冀,警方通過查閱死者的電腦和手機舞丛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來果漾,“玉大人球切,你說我怎么就攤上這事∪拚希” “怎么了吨凑?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長户辱。 經(jīng)常有香客問我鸵钝,道長,這世上最難降的妖魔是什么庐镐? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任恩商,我火速辦了婚禮,結(jié)果婚禮上必逆,老公的妹妹穿的比我還像新娘怠堪。我一直安慰自己,他們只是感情好名眉,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布粟矿。 她就那樣靜靜地躺著,像睡著了一般损拢。 火紅的嫁衣襯著肌膚如雪陌粹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天福压,我揣著相機與錄音掏秩,去河邊找鬼绘证。 笑死,一個胖子當(dāng)著我的面吹牛哗讥,可吹牛的內(nèi)容都是我干的嚷那。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼杆煞,長吁一口氣:“原來是場噩夢啊……” “哼魏宽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起决乎,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤队询,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后构诚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚌斩,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年范嘱,在試婚紗的時候發(fā)現(xiàn)自己被綠了送膳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡丑蛤,死狀恐怖叠聋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情受裹,我是刑警寧澤碌补,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站棉饶,受9級特大地震影響厦章,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜照藻,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一袜啃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岩梳,春花似錦囊骤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至列疗,卻和暖如春滑蚯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工告材, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坤次,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓斥赋,卻偏偏與公主長得像缰猴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子疤剑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • HashMap 底層分析 以下基于 JDK1.7 分析滑绒。 容量 負載因子 容量的默認大小是 16,負載因子是 0....
    luke_閱讀 280評論 0 0
  • 以下基于 JDK1.7 分析隘膘。 如圖所示疑故,HashMap 底層是基于數(shù)組和鏈表實現(xiàn)的。其中有兩個重要的參數(shù): 容量...
    程序員生涯閱讀 751評論 0 0
  • 移步數(shù)據(jù)結(jié)構(gòu)--容器匯總(java & Android)由于 HashMap 底層涉及到太多方面弯菊,一篇文章總是不能...
    凱玲之戀閱讀 831評論 0 5
  • 瀟華日日新第34天《高效演講》 既然已經(jīng)決定要把魚放在桌子上纵势,直面溝通問題,那么你就要制定一...
    瀟華閱讀 1,026評論 0 1
  • “她有什么呀育瓜,不就是一張臉還看的過去么≡岳茫”“是啊。那就夠了呀恋脚∠侔欤”“……” 看過一個電視劇,名字叫做《你好糟描,喬安》 ...
    CrystalUU閱讀 488評論 0 8