JAVA8對HashMap擴容機制的優(yōu)化

如果 HashMap 的 table 長度為 M荒叶,全部存儲的鍵值對數(shù)量為 N瘦穆,如果哈希函數(shù)滿足均勻性的要求闪湾,那么每條鏈表的長度大約為 N/M早处,因此平均查找次數(shù)的復雜度為 O(N/M)。

為了讓提高查找效率椒丧,需要降低每條鏈表的長度壹甥,也就是說 table 要盡可能大。HashMap 采用動態(tài)擴容來根據(jù)當前的 N 值來調(diào)整 M 值壶熏,使得空間效率和時間效率都能得到保證句柠。

關于JAVA7中的擴容機制不了解的 大家可以先參考這篇文章# 博客園java容器03--HashMap源碼分析

JAVA7擴容后的rehash過程使用了單鏈表的頭插法方式,同一位置上新元素總會被放在鏈表的頭部位置棒假;這樣如果發(fā)生了hash沖突的話先放在一個索引上的元素終會被放到Entry鏈的尾部溯职,這一點和JAVA8有區(qū)別。

JAVA8在rehash算法利用了下面的一個特性:
HashMap的擴容使用的是2次冪的擴展(指長度擴為原來2倍)帽哑,所以谜酒,元素的位置要么是在原位置,要么是在原位置再移動2次冪的位置妻枕。什么意思呢僻族? 我們舉個例子說明。

假設原數(shù)組長度 capacity 為 16屡谐,擴容之后 new capacity 為 32:

old capacity : 00010000
new capacity : 00100000

根據(jù)HashMap如何計算Entry在桶中的下標述么?一文中,
下標的計算方法愕掏,對于一個 Key度秘,如原Hash值 key1 = 0001 1001 key2 = 0000 1001
擴容前 hash & (length - 1) :
key1 : 0001 1001 & 0000 1111 -> 0000 1001
key2 : 0000 1001 & 0000 1111 -> 0000 1001

擴容后 hash & (length - 1) :
key1 : 0001 1001 & 0001 1111 -> 0001 1001
key2 : 0000 1001 & 0001 1111 -> 0000 1001

因此,我們在擴充HashMap的時候饵撑,不需要像JDK1.7的實現(xiàn)那樣重新計算hash剑梳,
**只需要看原來的hash值在擴容后新增的那一位是1還是0唆貌,如果是0的話索引沒變,是1的話索引變成“原索引+oldCap” 阻荒。

在JAVA8代碼中挠锥,抽象為一行if判斷代碼 :
if ((e.hash & oldCap) == 0
即如果位與原來的capacity結(jié)果為0 則代表hash值新增的高位為0。

jdk1.8 hashMap擴容例圖.png

這種算法既省去了重新計算hash值的時間侨赡,而且新增的1位是0還是1機會是隨機的蓖租,因此resize的過程,均勻的把之前的沖突的節(jié)點分散到新的bucket了羊壹。
這就是JAVA8新增的優(yōu)化點:
在JAVA7中rehash舊鏈表遷移新鏈表的時候蓖宦,如果在新表的數(shù)組索引位置相同,則鏈表元素會倒置油猫,但是從上圖可以看出稠茂,而在JAVA8中不會倒置。

參考:
http://www.importnew.com/20386.html
https://www.cnblogs.com/csslcww/p/9611568.html

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末情妖,一起剝皮案震驚了整個濱河市睬关,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毡证,老刑警劉巖电爹,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異料睛,居然都是意外死亡丐箩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門恤煞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屎勘,“玉大人,你說我怎么就攤上這事居扒「攀” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵喜喂,是天一觀的道長瓤摧。 經(jīng)常有香客問我,道長夜惭,這世上最難降的妖魔是什么姻灶? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任铛绰,我火速辦了婚禮诈茧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捂掰。我一直安慰自己敢会,他們只是感情好曾沈,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸥昏,像睡著了一般塞俱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吏垮,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天障涯,我揣著相機與錄音,去河邊找鬼膳汪。 笑死唯蝶,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遗嗽。 我是一名探鬼主播粘我,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痹换!你這毒婦竟也來了征字?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤娇豫,失蹤者是張志新(化名)和其女友劉穎匙姜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锤躁,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡搁料,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了系羞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郭计。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖椒振,靈堂內(nèi)的尸體忽然破棺而出昭伸,到底是詐尸還是另有隱情,我是刑警寧澤澎迎,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布庐杨,位于F島的核電站,受9級特大地震影響夹供,放射性物質(zhì)發(fā)生泄漏灵份。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一哮洽、第九天 我趴在偏房一處隱蔽的房頂上張望填渠。 院中可真熱鬧,春花似錦、人聲如沸氛什。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枪眉。三九已至捺檬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贸铜,已是汗流浹背堡纬。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒿秦,地道東北人隐轩。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像渤早,于是被迫代替她去往敵國和親职车。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

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

  • HashMap 一直是非常常用的數(shù)據(jù)結(jié)構(gòu)鹊杖,也是面試中十分常問到的集合類型悴灵,今天就來說說 HashMap。但是為什么...
    Howie_Y閱讀 9,266評論 0 13
  • 1.概述 HashMap是日常java開發(fā)中常用的類之一,是java設計中非常經(jīng)典的一個類登下,它巧妙的設計思想與實現(xiàn)...
    Garwer閱讀 2,228評論 1 28
  • 如果說Java的HashMap是數(shù)組+鏈表茫孔,那么JDK 8之后就是數(shù)組+鏈表+紅黑樹組成了HashMap。 在之前...
    Java_Explorer閱讀 999評論 1 5
  • 總是很奇怪自己為什么能像野草一樣被芳,即便是烈火燎原缰贝,也固執(zhí)地相信春天會來,重生在即畔濒。這是一種下意識的自我保護剩晴,還是傻...
    yanzikuaile燕子閱讀 242評論 0 0
  • 今天聽書時有了解了一個新的概念,無為侵状。這本書是一個外國人寫的赞弥,專門將中國古人所講的無為這個概念。聽書的時候講到了中...
    鈐魚擺擺閱讀 331評論 0 1