摘要:調(diào)用方法看完可以知道邏輯是先通過(guò)計(jì)算出索引的位置,然后先檢查第一個(gè)節(jié)點(diǎn)看看是否是我們要的節(jié)點(diǎn),如果不是在去查看是否死紅黑樹(shù)和鏈表。
上文講到HashMap的增加方法,現(xiàn)在繼續(xù) [上文鏈接]()
HashMap在上一篇源碼分析的文章中,如果使用put的時(shí)候如果元素?cái)?shù)量超過(guò)threshold就會(huì)調(diào)用resize進(jìn)行擴(kuò)容
1.擴(kuò)容機(jī)制想要了解HashMap的擴(kuò)容機(jī)制你要有這兩個(gè)問(wèn)題
1.什么時(shí)候才需要擴(kuò)容
2.HashMap的擴(kuò)容是什么
在添加元素的時(shí)候如果超過(guò)threshold設(shè)置的閥值點(diǎn)就會(huì)進(jìn)行擴(kuò)容,簡(jiǎn)單的來(lái)說(shuō)就是一個(gè)水壺容量是二升,然后這個(gè)時(shí)候已經(jīng)滿了但是你還要繼續(xù)加水,咋辦?換個(gè)大的。所以HashMap的擴(kuò)容就和你這個(gè)水壺一樣,水已經(jīng)滿了那我就在換個(gè)大的水壺繼續(xù)加水。不過(guò)在你換水壺的時(shí)候是有很多條件的。
在我看這個(gè)resize的源碼的時(shí)候我也是一臉懵逼,最后請(qǐng)教了大佬得到的回答是因?yàn)?.8加入了紅黑樹(shù)比較麻煩可以看一下1.7的,然后我有去網(wǎng)上看了一下別人寫的文章基本上都是基于1.7的resize。所以這里就看1.7的resize來(lái)分析。
來(lái)看JDK1.7中resize的實(shí)現(xiàn)。
復(fù)制操作是調(diào)用的transfer方法
在1.7中的resize結(jié)合一下我們的小例子可以這樣理解,去超市買一個(gè)大一點(diǎn)的水壺,然后把以前水壺里面的水給倒進(jìn)新的水壺里面。再把我們當(dāng)前的水壺的容量替換掉,告訴別人我的容量更大了。(強(qiáng)行比喻哈哈哈哈哈)
1.7中的resize就是這么簡(jiǎn)單,那我們?cè)诳匆幌?.8中的resize(),這樣再看就不會(huì)一臉懵逼了
我在這里把1.8的resize方法分為兩部分
1.計(jì)算新的newCap(新的容量)和newThr(新閥值點(diǎn))
2.復(fù)制新的數(shù)組
第一部分
第二部分
對(duì)比一下1.7
1.7元素不需要更換位置。1.8元素的位置要么是在原位置,要么是在原位置再移動(dòng)2次冪的位置
不需要像1.7一樣重新計(jì)算hash
2.刪除刪除的話就是首先先找到元素的位置,如果是鏈表就遍歷鏈表找到元素之后刪除。如果是用紅黑樹(shù)就遍歷樹(shù)然后找到之后做刪除,樹(shù)小于6的時(shí)候要轉(zhuǎn)鏈表。
刪除方法:
調(diào)用removeNode:
3.查找元素查找方法,通過(guò)元素的Key找到Value。
調(diào)用getNode()方法
看完可以知道邏輯是先通過(guò)Key計(jì)算出索引的位置,然后先檢查第一個(gè)節(jié)點(diǎn)看看是否是我們要的節(jié)點(diǎn),如果不是在去查看是否死紅黑樹(shù)和鏈表。
4.遍歷我們通過(guò)下面幾個(gè)例子來(lái)演示一下HashMap怎么遍歷
1.分別遍歷Key和Values
for (String key:map.keySet()){ System.out.println(key); } for (Object value : map.values()) { System.out.println(value); }
2.迭代
Iterator> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry mapEntry = iterator.next(); System.out.println(mapEntry.getKey() + "====" + mapEntry.getValue()); }
3.獲取 key 集合
SetkeySet = map.keySet(); for (String str : keySet) { System.out.println(str + "====" + map.get(str)); }
4.獲取Entry 集合,遍歷Entry 集合
Set> entrySet = map.entrySet(); for (Map.Entry entry : entrySet) { System.out.println(entry.getKey() + "====" + entry.getValue()); }
對(duì)比來(lái)說(shuō)使用迭代的方式是最好的,也可以在迭代的時(shí)候?qū)系脑剡M(jìn)行刪除
總結(jié)基于JDK1.8的HashMap是由數(shù)組+鏈表+紅黑樹(shù)組成,當(dāng)鏈表長(zhǎng)度超過(guò) 8 時(shí)會(huì)自動(dòng)轉(zhuǎn)換成紅黑樹(shù),當(dāng)紅黑樹(shù)節(jié)點(diǎn)個(gè)數(shù)小于 6 時(shí),又會(huì)轉(zhuǎn)化成鏈表。相對(duì)于早期版本的 JDK HashMap 實(shí)現(xiàn),新增了紅黑樹(shù)作為底層數(shù)據(jù)結(jié)構(gòu),在數(shù)據(jù)量較大且哈希碰撞較多時(shí),能夠極大的增加檢索的效率。HashMap并不是線程安全的,支持K和V為null ,k重復(fù)會(huì)覆蓋,V可以重復(fù),還有一點(diǎn)HashMap遍歷的數(shù)據(jù)不是有序的是無(wú)序的
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75450.html
摘要:再者,現(xiàn)在互聯(lián)網(wǎng)的面試中上點(diǎn)的都會(huì)涉及一下或者的問(wèn)題個(gè)高級(jí)多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。假如源碼分析之掘金概念是中集合的一種實(shí)現(xiàn)。 攻破 JAVA NIO 技術(shù)壁壘 - 后端 - 掘金現(xiàn)在使用NIO的場(chǎng)景越來(lái)越多,很多網(wǎng)上的技術(shù)框架或多或少的使用NIO技術(shù),譬如Tomcat,Jetty。學(xué)習(xí)和掌握NIO技術(shù)已經(jīng)不是一個(gè)JAVA攻城獅...
摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長(zhǎng)度大于閾值默認(rèn)為時(shí),將鏈表轉(zhuǎn)化為紅黑樹(shù),以減少搜索時(shí)間。有序,唯一紅黑樹(shù)自平衡的排序二叉樹(shù)。 本文是最最最常見(jiàn)Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...
摘要:為了避免一篇文章的篇幅過(guò)長(zhǎng),于是一些比較大的主題就都分成幾篇來(lái)講了,這篇文章是筆者所有文章的目錄,將會(huì)持續(xù)更新,以給大家一個(gè)查看系列文章的入口。 前言 大家好,筆者是今年才開(kāi)始寫博客的,寫作的初衷主要是想記錄和分享自己的學(xué)習(xí)經(jīng)歷。因?yàn)閷懽鞯臅r(shí)候發(fā)現(xiàn),為了弄懂一個(gè)知識(shí),不得不先去了解另外一些知識(shí),這樣以來(lái),為了說(shuō)明一個(gè)問(wèn)題,就要把一系列知識(shí)都了解一遍,寫出來(lái)的文章就特別長(zhǎng)。 為了避免一篇...
摘要:為了避免一篇文章的篇幅過(guò)長(zhǎng),于是一些比較大的主題就都分成幾篇來(lái)講了,這篇文章是筆者所有文章的目錄,將會(huì)持續(xù)更新,以給大家一個(gè)查看系列文章的入口。 前言 大家好,筆者是今年才開(kāi)始寫博客的,寫作的初衷主要是想記錄和分享自己的學(xué)習(xí)經(jīng)歷。因?yàn)閷懽鞯臅r(shí)候發(fā)現(xiàn),為了弄懂一個(gè)知識(shí),不得不先去了解另外一些知識(shí),這樣以來(lái),為了說(shuō)明一個(gè)問(wèn)題,就要把一系列知識(shí)都了解一遍,寫出來(lái)的文章就特別長(zhǎng)。 為了避免一篇...
閱讀 2566·2021-10-11 10:58
閱讀 1064·2019-08-29 13:58
閱讀 1686·2019-08-26 13:32
閱讀 852·2019-08-26 10:40
閱讀 3288·2019-08-26 10:18
閱讀 1776·2019-08-23 14:18
閱讀 1130·2019-08-23 10:54
閱讀 458·2019-08-22 18:39