Hashmap1.7和1.8區(qū)別+ConcurrentHashmap1.7和1.8區(qū)別

Hashmap

JDK1.7中
使用一個Entry數(shù)組來存儲數(shù)據(jù)峭梳,用key的hashcode取模來決定key會被放到數(shù)組里的位置铡羡,如果hashcode相同拭嫁,或者hashcode取模后的結果相同,那么這些key會被定位到Entry數(shù)組的同一個格子里浮入,這些key會形成一個鏈表龙优;
在hash函數(shù)特別差的情況下,比如說所有key的hashcode都相同事秀,這個鏈表可能會很長彤断,那么put/get操作都可能需要遍歷這個鏈表,也就是最差情況下時間復雜度為O(n)易迹。

JDK1.8中
使用一個Node數(shù)組來存儲數(shù)據(jù)宰衙,但是這個Node可能是鏈表結構,也可能是紅黑樹結構睹欲;如果插入的元素key的hashcode值相同供炼,那么這些key也會被定位到Node數(shù)組的同一個格子里,如果不超過8個使用鏈表存儲窘疮,超過8個袋哼,會調(diào)用treeifyBin函數(shù),將鏈表轉換為紅黑樹闸衫。那么即使所有key的hashcode完全相同涛贯,由于紅黑樹的特點,查找某個特定元素楚堤,也只需要O(logn)的開銷疫蔓。
紅黑樹:
每個節(jié)點不是紅的就是黑的;
根節(jié)點是黑的身冬;
葉節(jié)點都是黑色衅胀,葉子節(jié)點指的是為空的節(jié)點;
如果一個節(jié)點是紅色的酥筝,那么子節(jié)點必須為黑色滚躯;
從一個節(jié)點到該節(jié)點的子孫節(jié)點的所有路徑上包含相同數(shù)目的黑節(jié)點。

ConcurrentHashMap

JDK1.7中

使用segment+hashentry來實現(xiàn)嘿歌。ConcurrentHashMap在初始化時掸掏,計算出segement數(shù)組的大小ssize和每個segment中HashEntry數(shù)組的大小cap,并初始化segement數(shù)組的第一個元素宙帝,其中ssize大小為2的冪次方丧凤,默認為16,cap大小也是2的冪次方步脓,最小值為2愿待。segement在實現(xiàn)上繼承了ReetrantLock浩螺,這樣就自帶了鎖的功能。

put實現(xiàn):當執(zhí)行put方法插入數(shù)據(jù)的時候仍侥,先通過hash值在segment中找到對應的位置要出,然后如果相應位置的segment還未初始化,則通過CAS進行賦值农渊,接著執(zhí)行segment對象的put方法通過加鎖機制插入數(shù)據(jù)患蹂。
size實現(xiàn):因為concurrenthashmap是可以并發(fā)插入數(shù)據(jù)的,所以準確計算元素時有一定的難度砸紊,所以是先采用不加鎖的方式传于,連續(xù)計算元素的個數(shù),最多計算3次批糟,如果前后兩次計算結果相同格了,那么說明元素個數(shù)是準確的;如果前后兩次計算結果都不相同徽鼎,則給每個segment加鎖盛末,再計算一次元素的個數(shù)。

JDK1.8中

放棄了segment的設計否淤,取而代之的是Node+CAS+Synchronized來保證并發(fā)安全悄但。只有在執(zhí)行第一次put方法時,才會調(diào)用initTable()初始化Node數(shù)組石抡。

put實現(xiàn):
如果Node還未初始化檐嚣,那么通過CAS插入相應的數(shù)據(jù);
如果Node不為空啰扛,且當前該節(jié)點不處于移動狀態(tài)嚎京,那么對該節(jié)點加synchronized鎖,如果該節(jié)點hash不小于0隐解,則遍歷鏈表更新節(jié)點或者插入新節(jié)點鞍帝;
如果該節(jié)點是TreeBin類型的節(jié)點,說明是紅黑樹結構煞茫,則通過putTreeVal方法往紅黑樹中插入節(jié)點帕涌;
如果binCount不為0,說明put操作對數(shù)據(jù)產(chǎn)生了影響续徽,如果當前鏈表的個數(shù)達到8個蚓曼,則通過treeifyBin方法轉化為紅黑樹,如果oldVal不為空钦扭,說明是一次更新操作纫版,沒有對元素個數(shù)產(chǎn)生影響,則直接返回舊值客情;
如果插入的是一個新節(jié)點其弊,則執(zhí)行addCount()方法嘗試更新元素個數(shù)baseCount会涎;
size實現(xiàn):1.8中使用一個volatile類型的變量baseCount記錄元素的個數(shù),當插入新數(shù)據(jù)或則刪除數(shù)據(jù)時瑞凑,會通過addCount()方法更新baseCount。因為元素個數(shù)保存baseCount中概页,部分元素的變化個數(shù)保存在CounterCell數(shù)組中籽御,通過累加baseCount和CounterCell數(shù)組中的數(shù)量,即可得到元素的總個數(shù)惰匙。
PS.兩者在1.8之前都是頭插技掏,1.8之后都是尾插。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末项鬼,一起剝皮案震驚了整個濱河市哑梳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绘盟,老刑警劉巖鸠真,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異龄毡,居然都是意外死亡吠卷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門沦零,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祭隔,“玉大人,你說我怎么就攤上這事路操〖部剩” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵屯仗,是天一觀的道長搞坝。 經(jīng)常有香客問我,道長祭钉,這世上最難降的妖魔是什么瞄沙? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮慌核,結果婚禮上距境,老公的妹妹穿的比我還像新娘。我一直安慰自己垮卓,他們只是感情好垫桂,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粟按,像睡著了一般诬滩。 火紅的嫁衣襯著肌膚如雪霹粥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天疼鸟,我揣著相機與錄音后控,去河邊找鬼。 笑死空镜,一個胖子當著我的面吹牛浩淘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吴攒,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼张抄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了洼怔?” 一聲冷哼從身側響起署惯,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镣隶,沒想到半個月后极谊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡矾缓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年怀酷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜闻。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜕依,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琉雳,到底是詐尸還是另有隱情样眠,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布翠肘,位于F島的核電站檐束,受9級特大地震影響,放射性物質發(fā)生泄漏束倍。R本人自食惡果不足惜被丧,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绪妹。 院中可真熱鬧甥桂,春花似錦、人聲如沸邮旷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婶肩。三九已至办陷,卻和暖如春貌夕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背民镜。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工啡专, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人制圈。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓植旧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親离唐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354