HashMap就是這么簡單

聲明,本文用得是jdk1.8

前面已經(jīng)講了Collection的總覽和剖析List集合以及散列表赏半、Map集合类咧、紅黑樹的基礎(chǔ)了:

Collection總覽

List集合就這么簡單

Map集合、散列表开伏、紅黑樹介紹

本篇主要講解HashMap飞醉,以及涉及到一些與hashtable的比較~

看這篇文章之前最好是有點數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ):

Java實現(xiàn)單向鏈表

棧和隊列就是這么簡單

二叉樹就這么簡單

當(dāng)然了冲茸,如果講得有錯的地方還請大家多多包涵并不吝在評論去指正~

一、HashMap剖析

首先看看HashMap的頂部注釋說了些什么:

再來看看HashMap的類繼承圖:

下面我們來看一下HashMap的屬性:

成員屬性有這么幾個:

再來看一下hashMap的一個內(nèi)部類Node:

我們知道Hash的底層是散列表缅帘,而在Java中散列表的實現(xiàn)是通過數(shù)組+鏈表的~

再來簡單看看put方法就可以印證我們的說法了:數(shù)組+鏈表-->散列表

我們可以簡單總結(jié)出HashMap:

無序轴术,允許為null,非同步

底層由散列表(哈希表)實現(xiàn)

初始容量和裝載因子對HashMap影響挺大的钦无,設(shè)置小了不好逗栽,設(shè)置大了也不好

1.1HashMap構(gòu)造方法

HashMap的構(gòu)造方法有4個:

在上面的構(gòu)造方法最后一行,我們會發(fā)現(xiàn)調(diào)用了tableSizeFor()失暂,我們進(jìn)去看看:

這是位運算算法彼宠,具體流程可參考:

https://www.cnblogs.com/loading4/p/6239441.html

https://blog.csdn.net/fan2012huan/article/details/51097331

看完上面可能會感到奇怪的是:為啥是將2的整數(shù)冪的數(shù)賦給threshold

threshold這個成員變量是閾值弟塞,決定了是否要將散列表再散列凭峡。它的值應(yīng)該是:capacity * load factor才對的。

其實這里僅僅是一個初始化决记,當(dāng)創(chuàng)建哈希表的時候摧冀,它會重新賦值的:

至于別的構(gòu)造方法都差不多,這里我就不細(xì)講了:

1.2put方法

put方法可以說是HashMap的核心,我們來看看:

我們來看看它是怎么計算哈希值的:

為什么要這樣干呢索昂?建车?我們一般來說直接將key作為哈希值不就好了嗎,做異或運算是干嘛用的椒惨?缤至?

我們看下來:

我們是根據(jù)key的哈希值來保存在散列表中的,我們表默認(rèn)的初始容量是16康谆,要放到散列表中领斥,就是0-15的位置上。也就是tab[i = (n - 1) & hash]秉宿。可以發(fā)現(xiàn)的是:在做&運算的時候屯碴,僅僅是后4位有效~那如果我們key的哈希值高位變化很大描睦,低位變化很小。直接拿過去做&運算导而,這就會導(dǎo)致計算出來的Hash值相同的很多忱叭。

而設(shè)計者將key的哈希值的高位也做了運算(與高16位做異或運算,使得在做&運算時今艺,此時的低位實際上是高位與低位的結(jié)合)韵丑,這就增加了隨機(jī)性,減少了碰撞沖突的可能性虚缎!

下面我們再來看看流程是怎么樣的:

新值覆蓋舊值撵彻,返回舊值測試:

接下來我們看看resize()方法,在初始化的時候要調(diào)用這個方法实牡,當(dāng)散列表元素大于capacity * load factor的時候也是調(diào)用resize()

1.3get方法

接下來我們看看getNode()是怎么實現(xiàn)的:

1.4remove方法

再來看看removeNode()的實現(xiàn):

二陌僵、HashMap與Hashtable對比

從存儲結(jié)構(gòu)和實現(xiàn)來講基本上都是相同的。它和HashMap的最大的不同是它是線程安全的创坞,另外它不允許key和value為null碗短。Hashtable是個過時的集合類,不建議在新代碼中使用题涨,不需要線程安全的場合可以用HashMap替換偎谁,需要線程安全的場合可以用ConcurrentHashMap替換

Hashtable具體閱讀源碼可參考:

https://blog.csdn.net/panweiwei1994/article/details/77427010

https://blog.csdn.net/panweiwei1994/article/details/77428710

三、總結(jié)

在JDK8中HashMap的底層是:數(shù)組+鏈表(散列表)+紅黑樹

在散列表中有裝載因子這么一個屬性纲堵,當(dāng)裝載因子*初始容量小于散列表元素時巡雨,該散列表會再散列,擴(kuò)容2倍席函!

裝載因子的默認(rèn)值是0.75鸯隅,無論是初始大了還是初始小了對我們HashMap的性能都不好

裝載因子初始值大了,可以減少散列表再散列(擴(kuò)容的次數(shù)),但同時會導(dǎo)致散列沖突的可能性變大(散列沖突也是耗性能的一個操作蝌以,要得操作鏈表(紅黑樹)炕舵!

裝載因子初始值小了,可以減小散列沖突的可能性跟畅,但同時擴(kuò)容的次數(shù)可能就會變多咽筋!

初始容量的默認(rèn)值是16,它也一樣徊件,無論初始大了還是小了奸攻,對我們的HashMap都是有影響的:

初始容量過大,那么遍歷時我們的速度就會受影響~

初始容量過小虱痕,散列表再散列(擴(kuò)容的次數(shù))可能就變得多睹耐,擴(kuò)容也是一件非常耗費性能的一件事~

從源碼上我們可以發(fā)現(xiàn):HashMap并不是直接拿key的哈希值來用的,它會將key的哈希值的高16位進(jìn)行異或操作部翘,使得我們將元素放入哈希表的時候增加了一定的隨機(jī)性硝训。

還要值得注意的是:并不是桶子上有8位元素的時候它就能變成紅黑樹,它得同時滿足我們的散列表容量大于64才行的~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末新思,一起剝皮案震驚了整個濱河市窖梁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夹囚,老刑警劉巖纵刘,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荸哟,居然都是意外死亡假哎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門鞍历,熙熙樓的掌柜王于貴愁眉苦臉地迎上來位谋,“玉大人,你說我怎么就攤上這事堰燎√透福” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵秆剪,是天一觀的道長赊淑。 經(jīng)常有香客問我,道長仅讽,這世上最難降的妖魔是什么陶缺? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮洁灵,結(jié)果婚禮上饱岸,老公的妹妹穿的比我還像新娘掺出。我一直安慰自己,他們只是感情好苫费,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布汤锨。 她就那樣靜靜地躺著,像睡著了一般百框。 火紅的嫁衣襯著肌膚如雪闲礼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天铐维,我揣著相機(jī)與錄音褂始,去河邊找鬼能扒。 笑死唇兑,一個胖子當(dāng)著我的面吹牛厦坛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睬棚,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼第煮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闸拿?” 一聲冷哼從身側(cè)響起空盼,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤书幕,失蹤者是張志新(化名)和其女友劉穎新荤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體台汇,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡苛骨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苟呐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痒芝。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牵素,靈堂內(nèi)的尸體忽然破棺而出严衬,到底是詐尸還是另有隱情,我是刑警寧澤笆呆,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布请琳,位于F島的核電站,受9級特大地震影響赠幕,放射性物質(zhì)發(fā)生泄漏俄精。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一榕堰、第九天 我趴在偏房一處隱蔽的房頂上張望竖慧。 院中可真熱鬧,春花似錦、人聲如沸圾旨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碳胳。三九已至勇蝙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挨约,已是汗流浹背味混。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留诫惭,地道東北人翁锡。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像夕土,于是被迫代替她去往敵國和親馆衔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

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