HashMap的為啥用尾插法?

一.那么關(guān)于遇到hash沖突時候這個數(shù)據(jù)是頭插呢?還是尾插呢?

關(guān)于HashMap鏈表插入問題,java8之前之前是頭插法
頭插法:就是說新來的值會取代原有的值绎谦,原有的值就順推到鏈表中去福澡,就像上面的例子一樣,因為寫這個代碼的作者認(rèn)為后來的值被查找的可能性更大一點胧华,提升查找的效率。
java8之后彻秆,都是所用尾部插入了柬泽。

\color{red}{java8后為啥改為尾部插入呢?}


解決上面的問題需要一些預(yù)備知識


hashmap的擴容原理

hashmap擴容分為兩步

  • 擴容:創(chuàng)建一個新的Entry空數(shù)組框喳,長度是原數(shù)組的2倍课幕。
  • ReHash:遍歷原Entry數(shù)組,把所有的Entry重新Hash到新數(shù)組五垮。

為什么要重新Hash呢乍惊,不直接復(fù)制過去呢?
因為長度擴大以后放仗,Hash的規(guī)則也隨之改變润绎。
Hash的公式---> index = HashCode(Key) & (Length - 1)
原來長度(Length)是8你位運算出來的值是2 ,新的長度是16你位運算出來的值明顯不一樣了,之前的所有數(shù)據(jù)的hash值得到的位置都需要變化诞挨。
如下圖:
擴容前:


擴容后:

\color{red}{java8后為啥改為尾部插入呢莉撇?}
主要是為了安全,防止環(huán)化
因為resize的賦值方式,也就是使用了單鏈表的頭插入方式惶傻,同一位置上新元素總會被放在鏈表的頭部位置棍郎,在舊數(shù)組中同一條Entry鏈上的元素,通過重新計算索引位置后达罗,有可能被放到了新數(shù)組的不同位置上坝撑。

就可能出現(xiàn)下面的情況,大家發(fā)現(xiàn)問題沒有粮揉?

B的下一個指針指向了A

一旦幾個線程都調(diào)整完成巡李,就可能出現(xiàn)環(huán)形鏈表

如果這個時候去取值,就出現(xiàn)了無限循環(huán)的狀態(tài)..

使用頭插會改變鏈表的上的順序扶认,但是如果使用尾插侨拦,在擴容時會保持鏈表元素原本的順序,就不會出現(xiàn)鏈表成環(huán)的問題了

Java8在同樣的前提下并不會引起死循環(huán)辐宾,原因是擴容轉(zhuǎn)移后前后鏈表順序不變狱从,保持之前節(jié)點的引用關(guān)系。

那是不是意味著Java8就可以把HashMap用在多線程中呢叠纹?
那是必然不可以的,HashMap put/get方法都沒有加同步鎖季研,這里存在一個并發(fā)修改的問題,ConcurrentModifyExcption,所以線程安全還是無法保證誉察。

二 .那我問你HashMap的默認(rèn)初始化長度是多少与涡?16,為啥是16呢?

為了能讓 HashMap 存取高效,盡量較少碰撞,也就是要盡量把數(shù)據(jù)分配均勻驼卖。我們上面也講到了過了氨肌,Hash 值的范圍值-2147483648到2147483647,前后加起來大概40億的映射空間酌畜,只要哈希函數(shù)映射得比較均勻松散怎囚,一般應(yīng)用是很難出現(xiàn)碰撞的。但問題是一個40億長度的數(shù)組桥胞,內(nèi)存是放不下的恳守。所以這個散列值是不能直接拿來用的。用之前還要先做對數(shù)組的長度取模運算埠戳,得到的余數(shù)才能用來要存放的位置也就是對應(yīng)的數(shù)組下標(biāo)井誉。這個數(shù)組下標(biāo)的計算方法是“ (n - 1) & hash ”。(n代表數(shù)組長度)整胃。這也就解釋了 HashMap 的長度為什么是2的冪次方。

這個算法應(yīng)該如何設(shè)計呢喳钟?
我們首先可能會想到采用%取余的操作來實現(xiàn)屁使。但是,\color{red}{重點來了:取余操作中如果除數(shù)是2的冪次則等價于與其除數(shù)減一的與操作}
(也就是說 hash%length==hash&(length-1)的前提是 length 是2的 n 次方奔则;)蛮寂。”
\color{red}{并且采用二進制位操作 ,相對于取余操作能夠提高運算效率易茬,這就解釋了 HashMap 的長度為什么是2的冪次方酬蹋。}
詳細(xì)請看

至于為啥初始長度是16我覺得就是大家都覺得16通常情況夠用了吧.如果你有其他看法可以評論

三 .為啥我們重寫equals方法的時候需要重寫hashCode方法呢?

因為在java中抽莱,所有的對象都是繼承于Object類范抓。
Ojbect類中有兩個方法equals、hashCode食铐,這兩個方法都是用來比較兩個對象是否相等的匕垫。

在未重寫equals方法我們是繼承了object的equals方法,那里的 equals是比較兩個對象的內(nèi)存地址虐呻,顯然我們new了2個對象內(nèi)存地址肯定不一樣

對于值對象象泵,==比較的是兩個對象的值
對于引用對象,比較的是兩個對象的地址

所以如果我們對equals方法進行了重寫斟叼,建議一定要對hashCode方法重寫偶惠,以保證相同的對象返回相同的hash值,不同的對象返回不同的hash值朗涩。

不然一個鏈表的對象忽孽,你哪里知道你要找的是哪個,到時候發(fā)現(xiàn)hashCode都一樣,這不是完犢子嘛扒腕。

關(guān)于本文中頭插法尾插法詳情可看碼農(nóng)屆網(wǎng)紅敖丙的原文https://juejin.im/user/59b416065188257e671b670a/posts
但是我覺得這篇文章寫的比較簡略,面向面試還行,如果要了解基本原理建議大家可以看看https://blog.csdn.net/thqtzq/article/details/90485663

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绢淀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瘾腰,更是在濱河造成了極大的恐慌皆的,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹋盆,死亡現(xiàn)場離奇詭異费薄,居然都是意外死亡,警方通過查閱死者的電腦和手機栖雾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門楞抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人析藕,你說我怎么就攤上這事召廷。” “怎么了账胧?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵竞慢,是天一觀的道長。 經(jīng)常有香客問我治泥,道長筹煮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任居夹,我火速辦了婚禮败潦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘准脂。我一直安慰自己劫扒,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布意狠。 她就那樣靜靜地躺著粟关,像睡著了一般。 火紅的嫁衣襯著肌膚如雪环戈。 梳的紋絲不亂的頭發(fā)上闷板,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機與錄音院塞,去河邊找鬼遮晚。 笑死,一個胖子當(dāng)著我的面吹牛拦止,可吹牛的內(nèi)容都是我干的县遣。 我是一名探鬼主播糜颠,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼萧求!你這毒婦竟也來了其兴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤夸政,失蹤者是張志新(化名)和其女友劉穎元旬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體守问,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡匀归,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耗帕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穆端。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仿便,靈堂內(nèi)的尸體忽然破棺而出体啰,到底是詐尸還是另有隱情,我是刑警寧澤探越,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布狡赐,位于F島的核電站,受9級特大地震影響钦幔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜常柄,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一鲤氢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧西潘,春花似錦卷玉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至品姓,卻和暖如春寝并,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腹备。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工衬潦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人植酥。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓镀岛,卻偏偏與公主長得像弦牡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子漂羊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

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