問(wèn)與答 · JAVA基礎(chǔ)

emm...

HashMap的源碼懈费,實(shí)現(xiàn)原理锌钮,JDK8中對(duì)HashMap做了怎樣的優(yōu)化告希。

  • 數(shù)組:數(shù)組存儲(chǔ)區(qū)間是連續(xù)的扑浸,占用內(nèi)存嚴(yán)重,故空間復(fù)雜的很大燕偶。但數(shù)組的二分查找時(shí)間復(fù)雜度小喝噪,為O(1);數(shù)組的特點(diǎn)是:尋址容易指么,插入和刪除困難酝惧;

  • 鏈表:鏈表存儲(chǔ)區(qū)間離散,占用內(nèi)存比較寬松伯诬,故空間復(fù)雜度很小晚唇,但時(shí)間復(fù)雜度很大,達(dá)O(N)盗似。鏈表的特點(diǎn)是:尋址困難哩陕,插入和刪除容易。

  • 哈希表:那么我們能不能綜合兩者的特性赫舒,做出一種尋址容易悍及,插入刪除也容易的數(shù)據(jù)結(jié)構(gòu),這就是我們要提起的哈希表接癌。哈希表((Hash table)既滿足了數(shù)據(jù)的查找方便心赶,同時(shí)不占用太多的內(nèi)容空間,使用也十分方便缺猛。哈希表有多種不同的實(shí)現(xiàn)方法缨叫,我們可以理解為“鏈表的數(shù)組”。

哈希表是由 數(shù)組 + 鏈表 組成的荔燎,一個(gè)長(zhǎng)度為 16 的數(shù)組中耻姥,每個(gè)元素存儲(chǔ)的是一個(gè)鏈表的頭結(jié)點(diǎn)。那么這些元素是按照什么樣的規(guī)則存儲(chǔ)到數(shù)組中呢湖雹。一般情況是通過(guò) hash(key)%len 獲得咏闪,也就是元素的key的哈希值對(duì)數(shù)組長(zhǎng)度取模得到。比如上述哈希表中摔吏, 12%16=12 , 28%16=12 , 108%16=12 , 140%16=12 鸽嫂。所以 1228 征讲、 108 以及 140 都存儲(chǔ)在數(shù)組下標(biāo)為 12 的位置据某。

JDK8中,HashMap 加入了紅黑樹(shù)的使用诗箍,當(dāng)節(jié)點(diǎn)長(zhǎng)度大于8并且數(shù)組的長(zhǎng)度大于64時(shí)癣籽,該節(jié)點(diǎn)鏈表就會(huì)轉(zhuǎn)化成紅黑樹(shù)。數(shù)組長(zhǎng)度小于64并且節(jié)點(diǎn)長(zhǎng)度大于8時(shí),僅僅擴(kuò)容筷狼,并不會(huì)將鏈表轉(zhuǎn)換成紅黑樹(shù)瓶籽。

相關(guān)文獻(xiàn) -> http://www.importnew.com/28263.html

HaspMap擴(kuò)容是怎樣擴(kuò)容的,為什么都是2的N次冪的大小埂材。

HashMap計(jì)算 Key 值在數(shù)組中的位置是使用 Key.hashcode()數(shù)組長(zhǎng)度減一 進(jìn)行 & 運(yùn)算塑顺。當(dāng)長(zhǎng)度是 2 的N次冪時(shí),數(shù)組長(zhǎng)度減一 的二進(jìn)制實(shí)則為 N-1個(gè)1俏险。進(jìn)行與或運(yùn)算時(shí)严拒,能夠快速取到小于自己的一個(gè)整數(shù)。比 % 取模速度更快竖独。

HashMap裤唠,HashTable,ConcurrentHashMap的區(qū)別莹痢。

  • HashMap是非線程安全的种蘸,HashTable是線程安全的,內(nèi)部的方法基本都經(jīng)過(guò)synchronized修飾竞膳。因?yàn)橥脚搿⒐P阅艿仍颍阅芸隙ㄊ荋ashMap更佳顶猜,因此HashTable已被淘汰。

  • HashMap的鍵和值都允許有null存在痘括,而HashTable則都不行长窄,在HashTable中put進(jìn)的鍵值只要有一個(gè)null,直接拋出NullPointerException纲菌。

  • ConcurrentHashMap是線程安全的HashMap的實(shí)現(xiàn)挠日。HashTable里使用的是synchronized關(guān)鍵字,這其實(shí)是對(duì)對(duì)象加鎖翰舌,鎖住的都是對(duì)象整體嚣潜,當(dāng)Hashtable的大小增加到一定的時(shí)候,性能會(huì)急劇下降椅贱,因?yàn)榈鷷r(shí)需要被鎖定很長(zhǎng)的時(shí)間懂算。

  • ConcurrentHashMap引入了分割(Segment),上面代碼中的最后一行其實(shí)就可以理解為把一個(gè)大的Map拆分成N個(gè)小的HashTable庇麦,在put方法中计技,會(huì)根據(jù)hash(paramK.hashCode())來(lái)決定具體存放進(jìn)哪個(gè)Segment,如果查看Segment的put操作山橄,我們會(huì)發(fā)現(xiàn)內(nèi)部使用的同步機(jī)制是基于lock操作的垮媒,這樣就可以對(duì)Map的一部分(Segment)進(jìn)行上鎖,這樣影響的只是將要放入同一個(gè)Segment的元素的put操作,保證同步的時(shí)候睡雇,鎖住的不是整個(gè)Map(HashTable就是這么做的)萌衬,相對(duì)于HashTable提高了多線程環(huán)境下的性能,因此HashTable已經(jīng)被淘汰了它抱。

極高并發(fā)下HashTable和ConcurrentHashMap哪個(gè)性能好秕豫,如何實(shí)現(xiàn)的。

上個(gè)問(wèn)題已經(jīng)回答了抗愁,在極高并發(fā)下ConcurrentHashMap的性能要好于HashTable馁蒂,因?yàn)镃oncurrentHashMap采用的是分段鎖,不會(huì)造成整個(gè)對(duì)象鎖住蜘腌,在高并發(fā)時(shí)性能明顯好于Hashtable沫屡。

HashMap在高并發(fā)下如果沒(méi)有處理線程安全會(huì)有怎樣的安全隱患,具體表現(xiàn)是什么撮珠。

  • 多線程put時(shí)可能導(dǎo)致元素丟失沮脖,原因:當(dāng)多個(gè)線程同時(shí)執(zhí)行addEntry(hash,key ,value,i)時(shí),如果產(chǎn)生哈希碰撞芯急,導(dǎo)致兩個(gè)線程得到同樣的bucketIndex去存儲(chǔ)勺届,就可能會(huì)發(fā)生元素覆蓋丟失的情況

  • 多線程put時(shí)可能會(huì)導(dǎo)致get無(wú)限循環(huán),具體表現(xiàn)為CPU使用率100%娶耍;原因:在向HashMap put元素時(shí)免姿,會(huì)檢查HashMap的容量是否足夠,如果不足榕酒,則會(huì)新建一個(gè)比原來(lái)容量大兩倍的Hash表胚膊,然后把數(shù)組從老的Hash表中遷移到新的Hash表中,遷移的過(guò)程就是一個(gè)rehash()的過(guò)程想鹰,多個(gè)線程同時(shí)操作就有可能會(huì)形成循環(huán)鏈表紊婉,所以在使用get()時(shí),就會(huì)出現(xiàn)Infinite Loop的情況辑舷。

相關(guān)文獻(xiàn) -> https://www.cnblogs.com/hunrry/p/9183027.html

java中四種修飾符的限制范圍喻犁。

  • private: Java語(yǔ)言中對(duì)訪問(wèn)權(quán)限限制的最窄的修飾符,一般稱之為“私有的”何缓。被其修飾的屬性以及方法只能被該類(lèi)的對(duì)象 訪問(wèn)肢础,其子類(lèi)不能訪問(wèn),更不能允許跨包訪問(wèn)碌廓。

  • default:即不加任何訪問(wèn)修飾符乔妈,通常稱為“默認(rèn)訪問(wèn)權(quán)限“或者“包訪問(wèn)權(quán)限”。該模式下氓皱,只允許在同一個(gè)包中進(jìn)行訪問(wèn)路召。

  • protected: 介于public 和 private 之間的一種訪問(wèn)修飾符勃刨,一般稱之為“保護(hù)訪問(wèn)權(quán)限”。被其修飾的屬性以及方法只能被類(lèi)本 身的方法及子類(lèi)訪問(wèn)股淡,即使子類(lèi)在不同的包中也可以訪問(wèn)身隐。

  • public: Java語(yǔ)言中訪問(wèn)限制最寬的修飾符,一般稱之為“公共的”。被其修飾的類(lèi)、屬性以及方法不僅可以跨類(lèi)訪問(wèn)澄暮,而且 允許跨包訪問(wèn)实檀。

Object類(lèi)中的方法略号。

clone()

clone()函數(shù)的用途是用來(lái)另存一個(gè)當(dāng)前存在的對(duì)象。

hashCode()和equals()

equals()用于確認(rèn)兩個(gè)對(duì)象是否相同,hashCode()用于獲取對(duì)象的哈希值,哈希值相同的對(duì)象不一定equals()叁巨,equale()返回true的兩個(gè)對(duì)象一定相同。

toString()

toString()返回一個(gè)String對(duì)象呐籽,用來(lái)標(biāo)識(shí)自己 锋勺。

getClass()

getClass()返回一個(gè)Class對(duì)象。因?yàn)榉祷氐氖且粋€(gè)class對(duì)象,后面可以跟class類(lèi)的方法狡蝶。用的是誰(shuí)的構(gòu)造函數(shù)庶橱,那么getClass返回的就是誰(shuí)的類(lèi)型,getClass()經(jīng)常用于java反射機(jī)制贪惹。

finalize()

這個(gè)函數(shù)在進(jìn)行垃圾回收的時(shí)候會(huì)用到苏章,匿名對(duì)象回收之前會(huì)調(diào)用到。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奏瞬,一起剝皮案震驚了整個(gè)濱河市布近,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丝格,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棵譬,死亡現(xiàn)場(chǎng)離奇詭異显蝌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)订咸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)曼尊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脏嚷,你說(shuō)我怎么就攤上這事骆撇。” “怎么了父叙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵神郊,是天一觀的道長(zhǎng)肴裙。 經(jīng)常有香客問(wèn)我,道長(zhǎng)涌乳,這世上最難降的妖魔是什么蜻懦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮夕晓,結(jié)果婚禮上宛乃,老公的妹妹穿的比我還像新娘。我一直安慰自己蒸辆,他們只是感情好征炼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著躬贡,像睡著了一般谆奥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逗宜,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天雄右,我揣著相機(jī)與錄音,去河邊找鬼纺讲。 笑死擂仍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熬甚。 我是一名探鬼主播逢渔,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乡括!你這毒婦竟也來(lái)了肃廓?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诲泌,失蹤者是張志新(化名)和其女友劉穎盲赊,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體敷扫,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哀蘑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葵第。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绘迁。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖卒密,靈堂內(nèi)的尸體忽然破棺而出缀台,到底是詐尸還是另有隱情,我是刑警寧澤哮奇,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布膛腐,位于F島的核電站睛约,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏依疼。R本人自食惡果不足惜痰腮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望律罢。 院中可真熱鬧膀值,春花似錦、人聲如沸误辑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)巾钉。三九已至翘狱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砰苍,已是汗流浹背潦匈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赚导,地道東北人茬缩。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吼旧,于是被迫代替她去往敵國(guó)和親凰锡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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

  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中圈暗,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后掂为,其對(duì)應(yīng)的棧就會(huì)被回收,此時(shí)员串,在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,413評(píng)論 1 14
  • Java SE 基礎(chǔ): 封裝勇哗、繼承、多態(tài) 封裝: 概念:就是把對(duì)象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體寸齐,并盡...
    Jayden_Cao閱讀 2,103評(píng)論 0 8
  • 九種基本數(shù)據(jù)類(lèi)型的大小欲诺,以及他們的封裝類(lèi)。(1)九種基本數(shù)據(jù)類(lèi)型和封裝類(lèi) (2)自動(dòng)裝箱和自動(dòng)拆箱 什么是自動(dòng)裝箱...
    關(guān)瑋琳l(shuí)inSir閱讀 1,882評(píng)論 0 47
  • 優(yōu)優(yōu): 此刻的你正做著甜甜的美夢(mèng)吧访忿。 小學(xué)生語(yǔ)文能力競(jìng)賽你以絕對(duì)優(yōu)勢(shì)闖入決賽,祝賀你哦斯稳。捷報(bào)頻傳海铆,你讓媽...
    曉寒iyoyo閱讀 163評(píng)論 0 1
  • 很高興自己已經(jīng)堅(jiān)持跑步21天,因?yàn)閳?jiān)持21天很可能會(huì)形成習(xí)慣挣惰。這21天中有兩天沒(méi)有跑步卧斟,有一天全天下雨殴边,還有一天打...
    魏魏說(shuō)閱讀 448評(píng)論 2 5