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