java集合面試題總結(jié)(1~20題)

1.? HashMap與HashTable的區(qū)別?

????????1.HashMap是非線程安全的竟纳,HashTable是線程安全的。

????????2.HashMap的鍵和值都允許有null值存在逊移,而HashTable則不行。

????????3.因?yàn)榫€程安全的問(wèn)題,HashMap效率比HashTable的要高玫膀。

? ? ? ? 4.默認(rèn)容量不同 (HashMap:16? HashTable:11)

2.? HashMap,ConcurrentHashMap與LinkedHashMap的區(qū)別爹脾?

????????ConcurrentHashMap是使用了鎖分段技術(shù)技術(shù)來(lái)保證線程安全的帖旨,鎖分段技術(shù):首先將數(shù)據(jù)分成一段一段的存儲(chǔ),然后給每一段數(shù)據(jù)配一把鎖灵妨,當(dāng)一個(gè)線程占用鎖訪問(wèn)其中一個(gè)段數(shù)據(jù)的時(shí)候解阅,其他段的數(shù)據(jù)也能被其他線程訪問(wèn)

????????ConcurrentHashMap 是在每個(gè)段(segment)中線程安全的

????????LinkedHashMap維護(hù)一個(gè)雙鏈表,可以將里面的數(shù)據(jù)按寫(xiě)入的順序讀出

3. ConcurrentHashMap應(yīng)用場(chǎng)景泌霍?

????????1:ConcurrentHashMap的應(yīng)用場(chǎng)景是高并發(fā)货抄,但是并不能保證線程安全,而同步的HashMap和HashMap的是鎖住整個(gè)容器朱转,而加鎖之后ConcurrentHashMap不需要鎖住整個(gè)容器蟹地,只需要鎖住對(duì)應(yīng)的Segment就好了,所以可以保證高并發(fā)同步訪問(wèn)肋拔,提升了效率锈津。

????????2:可以多線程寫(xiě)。

4.? ConcurrentHashMap把HashMap分成若干個(gè)Segmenet凉蜂?

????????1.get時(shí)琼梆,不加鎖,先定位到segment然后在找到頭結(jié)點(diǎn)進(jìn)行讀取操作窿吩。而value是volatile變量茎杂,所以可以保證在競(jìng)爭(zhēng)條件時(shí)保證讀取最新的值,如果讀到的value是null纫雁,則可能正在修改煌往,那么就調(diào)用ReadValueUnderLock函數(shù),加鎖保證讀到的數(shù)據(jù)是正確的。

????????2.Put時(shí)會(huì)加鎖刽脖,一律添加到hash鏈的頭部羞海。

????????3.Remove時(shí)也會(huì)加鎖,由于next是final類型不可改變曲管,所以必須把刪除的節(jié)點(diǎn)之前的節(jié)點(diǎn)都復(fù)制一遍却邓。

????????4.ConcurrentHashMap允許多個(gè)修改操作并發(fā)進(jìn)行,其關(guān)鍵在于使用了鎖分離技術(shù)院水。它使用了多個(gè)鎖來(lái)控制對(duì)Hash表的不同Segment進(jìn)行的修改腊徙。

????????ConcurrentHashMap能夠保證每一次調(diào)用都是原子操作,但是并不保證多次調(diào)用之間也是原子操作檬某。

5.??Java中Vector和ArrayList的區(qū)別?

? ? ? ?首先看這兩類都實(shí)現(xiàn)List接口撬腾,而List接口一共有三個(gè)實(shí)現(xiàn)類,分別是ArrayList恢恼、Vector和LinkedList民傻。List用于存放多個(gè)元素,能夠維護(hù)元素的次序场斑,并且允許元素的重復(fù)饰潜。3個(gè)具體實(shí)現(xiàn)類的相關(guān)區(qū)別如下:

????????ArrayList是最常用的List實(shí)現(xiàn)類,內(nèi)部是通過(guò)數(shù)組實(shí)現(xiàn)的和簸,它允許對(duì)元素進(jìn)行快速隨機(jī)訪問(wèn)。數(shù)組的缺點(diǎn)是每個(gè)元素之間不能有間隔碟刺,當(dāng)數(shù)組大小不滿足時(shí)需要增加存儲(chǔ)能力锁保,就要講已經(jīng)有數(shù)組的數(shù)據(jù)復(fù)制到新的存儲(chǔ)空間中。當(dāng)從ArrayList的中間位置插入或者刪除元素時(shí)半沽,需要對(duì)數(shù)組進(jìn)行復(fù)制爽柒、移動(dòng)、代價(jià)比較高者填。因此浩村,它適合隨機(jī)查找和遍歷,不適合插入和刪除占哟。

????????Vector與ArrayList一樣心墅,也是通過(guò)數(shù)組實(shí)現(xiàn)的,不同的是它支持線程的同步榨乎,即某一時(shí)刻只有一個(gè)線程能夠?qū)慥ector怎燥,避免多線程同時(shí)寫(xiě)而引起的不一致性,但實(shí)現(xiàn)同步需要很高的花費(fèi)蜜暑,因此铐姚,訪問(wèn)它比訪問(wèn)ArrayList慢。

????????LinkedList是用鏈表結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)的肛捍,很適合數(shù)據(jù)的動(dòng)態(tài)插入和刪除隐绵,隨機(jī)訪問(wèn)和遍歷速度比較慢之众。另外,他還提供了List接口中沒(méi)有定義的方法依许,專門用于操作表頭和表尾元素棺禾,可以當(dāng)作堆棧、隊(duì)列和雙向隊(duì)列使用悍手。

6.??HashMap帘睦、HashTable、LinkedHashMap和TreeMap用法和區(qū)別坦康?

????????Java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個(gè)接口java.util.Map竣付,它有四個(gè)實(shí)現(xiàn)類,分別是HashMap滞欠、HashTable古胆、LinkedHashMap和TreeMap。本節(jié)實(shí)例主要介紹這4中實(shí)例的用法和區(qū)別筛璧。

關(guān)鍵技術(shù)剖析:

Map用于存儲(chǔ)鍵值對(duì)逸绎,根據(jù)鍵得到值,因此不允許鍵重復(fù)夭谤,值可以重復(fù)棺牧。

????????(1)HashMap是一個(gè)最常用的Map,它根據(jù)鍵的hashCode值存儲(chǔ)數(shù)據(jù)朗儒,根據(jù)鍵可以直接獲取它的值颊乘,具有很快的訪問(wèn)速度。HashMap最多只允許一條記錄的鍵為null醉锄,不允許多條記錄的值為null乏悄。HashMap不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫(xiě)HashMap恳不,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致檩小。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力烟勋。

????????(2)Hashtable與HashMap類似规求,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步神妹,即任一時(shí)刻只有一個(gè)線程能寫(xiě)Hashtable颓哮,然而,這也導(dǎo)致了Hashtable在寫(xiě)入時(shí)會(huì)比較慢鸵荠。

????????(3)LinkedHashMap像HashMap一樣允許null key冕茅,內(nèi)部通過(guò)維護(hù)一個(gè)雙向鏈表,當(dāng)?shù)敵鰰r(shí)可以以插入順序(通常情況下是插入順序,還可以是訪問(wèn)順序)輸出姨伤,因此性能稍微比HashMap低一點(diǎn)哨坪。當(dāng)重新插入一條數(shù)據(jù)(也就是put一個(gè)已經(jīng)存在的key)時(shí)不會(huì)影響插入順序。LinkedHashMap讓用戶從未指定的乍楚、混亂順序的Map實(shí)現(xiàn)HashMap和HashTable中解脫出來(lái)当编。非同步的。并且與TreeMap相比徒溪,沒(méi)有增加插入代價(jià)忿偷。

????????(4)TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按升序排序臊泌,也可以指定排序的比較器鲤桥。當(dāng)用Iteraor遍歷TreeMap時(shí),得到的記錄是排過(guò)序的渠概。TreeMap的鍵和值都不能為空茶凳。非同步的。

? ? ? ? TreeMap 的底層就是一顆紅黑樹(shù)播揪,它的 containsKey , get , put and remove 方法的時(shí)間復(fù)雜度是 log(n) 贮喧,并且它是按照 key 的自然順序(或者指定排序)排列,與 LinkedHashMap 不同猪狈, LinkedHashMap 保證了元素是按照插入的順序排列箱沦。

? ??????TreeMap取出來(lái)的是排序后的鍵值對(duì)。但如果您要按自然順序或自定義順序遍歷鍵雇庙,那么TreeMap會(huì)更好饱普。

? ??????LinkedHashMap 是HashMap的一個(gè)子類,如果需要輸出的順序和輸入的相同

7.? 為什么用HashMap状共?

????????HashMap 是一個(gè)散列桶(數(shù)組和鏈表),它存儲(chǔ)的內(nèi)容是鍵值對(duì) key-value 映射

????????HashMap 采用了數(shù)組和鏈表的數(shù)據(jù)結(jié)構(gòu)谁帕,能在查詢和修改方便繼承了數(shù)組的線性查找和鏈表的尋址修改

????????HashMap 是非 synchronized峡继,所以 HashMap 很快

????????HashMap 可以接受 null 鍵和值,而 Hashtable 則不能(原因就是 equlas() 方法需要對(duì)象匈挖,因?yàn)?HashMap 是后出的 API 經(jīng)過(guò)處理才可以)

8.? 有什么方法可以減少碰撞碾牌?

????????擾動(dòng)函數(shù)可以減少碰撞

????????原理是如果兩個(gè)不相等的對(duì)象返回不同的 hashcode 的話,那么碰撞的幾率就會(huì)小些儡循。這就意味著存鏈表結(jié)構(gòu)減小舶吗,這樣取值的話就不會(huì)頻繁調(diào)用 equal 方法,從而提高 HashMap 的性能(擾動(dòng)即 Hash 方法內(nèi)部的算法實(shí)現(xiàn)择膝,目的是讓不同對(duì)象返回不同hashcode)誓琼。

????????使用不可變的、聲明作 final 對(duì)象,并且采用合適的 equals() 和 hashCode() 方法腹侣,將會(huì)減少碰撞的發(fā)生

????????不可變性使得能夠緩存不同鍵的 hashcode叔收,這將提高整個(gè)獲取對(duì)象的速度,使用 String傲隶、Integer 這樣的 wrapper 類作為鍵是非常好的選擇饺律。

????????為什么 String、Integer 這樣的 wrapper 類適合作為鍵跺株?

????????因?yàn)?String 是 final复濒,而且已經(jīng)重寫(xiě)了 equals() 和 hashCode() 方法了。不可變性是必要的乒省,因?yàn)闉榱艘?jì)算 hashCode()巧颈,就要防止鍵值改變,如果鍵值在放入時(shí)和獲取時(shí)返回不同的 hashcode 的話作儿,那么就不能從 HashMap 中找到你想要的對(duì)象洛二。

9.? HashMap 中 hash 函數(shù)怎么是實(shí)現(xiàn)的?

????????在 hashmap 中要找到某個(gè)元素,需要根據(jù) key 的 hash 值來(lái)求得對(duì)應(yīng)數(shù)組中的位置攻锰。如何計(jì)算這個(gè)位置就是 hash 算法晾嘶。

? ? ? ? hashmap 的數(shù)據(jù)結(jié)構(gòu)是數(shù)組和鏈表的結(jié)合,所以我們當(dāng)然希望這個(gè) hashmap 里面的元素位置盡量的分布均勻些娶吞,盡量使得每個(gè)位置上的元素?cái)?shù)量只有一個(gè)垒迂。那么當(dāng)我們用 hash 算法求得這個(gè)位置的時(shí)候,馬上就可以知道對(duì)應(yīng)位置的元素就是我們要的妒蛇,而不用再去遍歷鏈表机断。 所以,我們首先想到的就是把 hashcode 對(duì)數(shù)組長(zhǎng)度取模運(yùn)算绣夺。這樣一來(lái)吏奸,元素的分布相對(duì)來(lái)說(shuō)是比較均勻的。

? ? ? ?但是“奶账#”運(yùn)算的消耗還是比較大的奋蔚,能不能找一種更快速、消耗更小的方式烈钞?我們來(lái)看看 JDK1.8 源碼是怎么做的

? ? ? 右移16位泊碑,之后按位異或

? ? ? ?高16 bit 不變,低16 bit 和高16 bit 做了一個(gè)異或(得到的 hashcode 轉(zhuǎn)化為32位二進(jìn)制毯欣,前16位和后16位低16 bit和高16 bit做了一個(gè)異或)

? ? ? ?(n·1) & hash = -> 得到下標(biāo)

10.?拉鏈法導(dǎo)致的鏈表過(guò)深馒过,為什么不用二叉查找樹(shù)代替而選擇紅黑樹(shù)?為什么不一直使用紅黑樹(shù)酗钞?

????????之所以選擇紅黑樹(shù)是為了解決二叉查找樹(shù)的缺陷:二叉查找樹(shù)在特殊情況下會(huì)變成一條線性結(jié)構(gòu)(這就跟原來(lái)使用鏈表結(jié)構(gòu)一樣了腹忽,造成層次很深的問(wèn)題)来累,遍歷查找會(huì)非常慢。而紅黑樹(shù)在插入新數(shù)據(jù)后可能需要通過(guò)左旋留凭、右旋佃扼、變色這些操作來(lái)保持平衡。引入紅黑樹(shù)就是為了查找數(shù)據(jù)快蔼夜,解決鏈表查詢深度的問(wèn)題兼耀。我們知道紅黑樹(shù)屬于平衡二叉樹(shù),為了保持“平衡”是需要付出代價(jià)的求冷,但是該代價(jià)所損耗的資源要比遍歷線性鏈表要少瘤运。所以當(dāng)長(zhǎng)度大于8的時(shí)候,會(huì)使用紅黑樹(shù)匠题;如果鏈表長(zhǎng)度很短的話拯坟,根本不需要引入紅黑樹(shù),引入反而會(huì)慢韭山。

11. 說(shuō)說(shuō)你對(duì)紅黑樹(shù)的見(jiàn)解郁季?

紅黑樹(shù)

? ? ?每個(gè)節(jié)點(diǎn)非紅即黑

? ? ?根節(jié)點(diǎn)總是黑色的

? ? ?如果節(jié)點(diǎn)是紅色的,則它的子節(jié)點(diǎn)必須是黑色的(反之不一定)

? ? 每個(gè)葉子節(jié)點(diǎn)都是黑色的空節(jié)點(diǎn)(NIL節(jié)點(diǎn))

? ? 從根節(jié)點(diǎn)到葉節(jié)點(diǎn)或空子節(jié)點(diǎn)的每條路徑钱磅,必須包含相同數(shù)目的黑色節(jié)點(diǎn)(即相同的黑色高度)

12.?如果 HashMap(jdk8) 的大小超過(guò)了負(fù)載因子(load factor)定義的容量怎么辦梦裂?

????????HashMap 默認(rèn)的負(fù)載因子大小為0.75。也就是說(shuō)盖淡,當(dāng)一個(gè) Map 填滿了75%的 bucket 時(shí)候年柠,和其它集合類一樣(如 ArrayList 等),將會(huì)創(chuàng)建原來(lái) HashMap 大小的兩倍的 bucket 數(shù)組來(lái)重新調(diào)整 Map 大小褪迟,并將原來(lái)的對(duì)象放入新的 bucket 數(shù)組中冗恨。這個(gè)過(guò)程叫作?rehashing

????????因?yàn)樗{(diào)用 hash 方法找到新的 bucket 位置味赃。這個(gè)值只可能在兩個(gè)地方掀抹,一個(gè)是原下標(biāo)的位置,另一種是在下標(biāo)為?<原下標(biāo)+原容量>?的位置心俗。

13. 重新調(diào)整 HashMap 大小存在什么問(wèn)題嗎渴丸?

????????重新調(diào)整 HashMap 大小的時(shí)候,確實(shí)存在條件競(jìng)爭(zhēng)另凌。

????????因?yàn)槿绻麅蓚€(gè)線程都發(fā)現(xiàn) HashMap 需要重新調(diào)整大小了,它們會(huì)同時(shí)試著調(diào)整大小戒幔。在調(diào)整大小的過(guò)程中吠谢,存儲(chǔ)在鏈表中的元素的次序會(huì)反過(guò)來(lái)。因?yàn)橐苿?dòng)到新的 bucket 位置的時(shí)候诗茎,HashMap 并不會(huì)將元素放在鏈表的尾部工坊,而是放在頭部献汗。這是為了避免尾部遍歷(tail traversing)。如果條件競(jìng)爭(zhēng)發(fā)生了王污,那么就死循環(huán)了罢吃。多線程的環(huán)境下不使用 HashMap。

????????為什么多線程會(huì)導(dǎo)致死循環(huán)昭齐,它是怎么發(fā)生的尿招?

????????HashMap 的容量是有限的。當(dāng)經(jīng)過(guò)多次元素插入阱驾,使得 HashMap 達(dá)到一定飽和度時(shí)就谜,Key 映射位置發(fā)生沖突的幾率會(huì)逐漸提高。這時(shí)候里覆, HashMap 需要擴(kuò)展它的長(zhǎng)度丧荐,也就是進(jìn)行Resize。

????????擴(kuò)容:創(chuàng)建一個(gè)新的 Entry 空數(shù)組喧枷,長(zhǎng)度是原數(shù)組的2倍

rehash:遍歷原 Entry 數(shù)組虹统,把所有的 Entry 重新 Hash 到新數(shù)組

? ? ? (友情鏈接:HashMap擴(kuò)容全過(guò)程

14、簡(jiǎn)單聊一下HashTable隧甚?

? ? ? ?HashTable的主要方法的源碼實(shí)現(xiàn)邏輯各薇,與HashMap中非常相似,有一點(diǎn)重大區(qū)別就是所有的操作都是通過(guò)synchronized鎖保護(hù)的涧窒。只有獲得了對(duì)應(yīng)的鎖空入,才能進(jìn)行后續(xù)的讀寫(xiě)等操作。

????????數(shù)組 + 鏈表方式存儲(chǔ)

????????默認(rèn)容量:11(質(zhì)數(shù)為宜)

????????put操作:首先進(jìn)行索引計(jì)算 (key.hashCode() & 0x7FFFFFFF)% table.length咖城;若在鏈表中找到了茬腿,則替換舊值,若未找到則繼續(xù)宜雀;當(dāng)總元素個(gè)數(shù)超過(guò) 容量 * 加載因子 時(shí)切平,擴(kuò)容為原來(lái) 2 倍并重新散列;將新元素加到鏈表頭部

????????對(duì)修改 Hashtable 內(nèi)部共享數(shù)據(jù)的方法添加了 synchronized辐董,保證線程安全

15悴品、可以使用 CocurrentHashMap 來(lái)代替 Hashtable 嗎?

????????我們知道 Hashtable 是 synchronized 的简烘,但是 ConcurrentHashMap 同步性能更好苔严,因?yàn)樗鼉H僅根據(jù)同步級(jí)別對(duì) map 的一部分進(jìn)行上鎖

????????ConcurrentHashMap 當(dāng)然可以代替 HashTable,但是 HashTable 提供更強(qiáng)的線程安全性

????????它們都可以用于多線程的環(huán)境孤澎,但是當(dāng) Hashtable 的大小增加到一定的時(shí)候届氢,性能會(huì)急劇下降,因?yàn)榈鷷r(shí)需要被鎖定很長(zhǎng)的時(shí)間覆旭。由于 ConcurrentHashMap 引入了分割(segmentation)退子,不論它變得多么大岖妄,僅僅需要鎖定 Map 的某個(gè)部分,其它的線程不需要等到迭代完成才能訪問(wèn) Map寂祥。簡(jiǎn)而言之荐虐,在迭代的過(guò)程中,ConcurrentHashMap 僅僅鎖定 Map 的某個(gè)部分丸凭,而 Hashtable 則會(huì)鎖定整個(gè) Map

16. ConcurrentHashMap 底層邏輯(JDK 1.7)福扬?

????????ConcurrentHashMap 是由 Segment 數(shù)組和 HashEntry 數(shù)組和鏈表組成

????????Segment 是基于重入鎖(ReentrantLock):一個(gè)數(shù)據(jù)段競(jìng)爭(zhēng)鎖。每個(gè) HashEntry 一個(gè)鏈表結(jié)構(gòu)的元素贮乳,利用 Hash 算法得到索引確定歸屬的數(shù)據(jù)段忧换,也就是對(duì)應(yīng)到在修改時(shí)需要競(jìng)爭(zhēng)獲取的鎖。ConcurrentHashMap 支持 CurrencyLevel(Segment 數(shù)組數(shù)量)的線程并發(fā)向拆。每當(dāng)一個(gè)線程占用鎖訪問(wèn)一個(gè) Segment 時(shí)亚茬,不會(huì)影響到其他的 Segment

????????核心數(shù)據(jù)如 value,以及鏈表都是 volatile 修飾的浓恳,保證了獲取時(shí)的可見(jiàn)性

????????首先是通過(guò) key 定位到 Segment刹缝,之后在對(duì)應(yīng)的 Segment 中進(jìn)行具體的 put 操作如下:

????????將當(dāng)前 Segment 中的 table 通過(guò) key 的 hashcode 定位到 HashEntry。

????????遍歷該 HashEntry颈将,如果不為空則判斷傳入的? key 和當(dāng)前遍歷的 key 是否相等梢夯,相等則覆蓋舊的 value

????????不為空則需要新建一個(gè) HashEntry 并加入到 Segment 中,同時(shí)會(huì)先判斷是否需要擴(kuò)容

????????最后會(huì)解除在 1 中所獲取當(dāng)前 Segment 的鎖晴圾。

????????雖然 HashEntry 中的 value 是用 volatile 關(guān)鍵詞修飾的颂砸,但是并不能保證并發(fā)的原子性,所以 put 操作時(shí)仍然需要加鎖處理

????????首先第一步的時(shí)候會(huì)嘗試獲取鎖死姚,如果獲取失敗肯定就有其他線程存在競(jìng)爭(zhēng)人乓,則利用 scanAndLockForPut() 自旋獲取鎖。

????????嘗試自旋獲取鎖

????????如果重試的次數(shù)達(dá)到了 MAX_SCAN_RETRIES 則改為阻塞鎖獲取都毒,保證能獲取成功色罚。最后解除當(dāng)前 Segment 的鎖

17. ConcurrentHashMap底層邏輯(JDK 1.8)?

????????CocurrentHashMap?拋棄了原有的 Segment 分段鎖账劲,采用了CAS + synchronized來(lái)保證并發(fā)安全性戳护。其中的val next?都用了 volatile 修飾,保證了可見(jiàn)性瀑焦。

????????最大特點(diǎn)是引入了 CAS

????????借助 Unsafe 來(lái)實(shí)現(xiàn) native code腌且。CAS有3個(gè)操作數(shù),內(nèi)存值 V榛瓮、舊的預(yù)期值 A铺董、要修改的新值 B。當(dāng)且僅當(dāng)預(yù)期值 A 和內(nèi)存值 V 相同時(shí)榆芦,將內(nèi)存值V修改為 B柄粹,否則什么都不做。Unsafe 借助 CPU 指令 cmpxchg 來(lái)實(shí)現(xiàn)匆绣。

put 過(guò)程

根據(jù) key 計(jì)算出 hashcode

判斷是否需要進(jìn)行初始化

通過(guò) key 定位出的 Node驻右,如果為空表示當(dāng)前位置可以寫(xiě)入數(shù)據(jù),利用 CAS 嘗試寫(xiě)入崎淳,失敗則自旋保證成功

如果當(dāng)前位置的 hashcode == MOVED == -1,則需要進(jìn)行擴(kuò)容

如果都不滿足堪夭,則利用 synchronized 鎖寫(xiě)入數(shù)據(jù)

如果數(shù)量大于 TREEIFY_THRESHOLD 則要轉(zhuǎn)換為紅黑樹(shù)

get 過(guò)程

根據(jù)計(jì)算出來(lái)的 hashcode 尋址,如果就在桶上那么直接返回值

如果是紅黑樹(shù)那就按照樹(shù)的方式獲取值

就不滿足那就按照鏈表的方式遍歷獲取值

18. hashMap(1.7) 擴(kuò)容的條件是什么拣凹?

? ? ? 數(shù)據(jù)結(jié)構(gòu):數(shù)組 + 鏈表?

????????擴(kuò)容必須滿足兩個(gè)條件:

? ??????1森爽、 存放新值的時(shí)候當(dāng)前已有元素的個(gè)數(shù)必須大于等于閾值

? ??????2、 存放新值的時(shí)候當(dāng)前存放數(shù)據(jù)發(fā)生hash碰撞(當(dāng)前key計(jì)算的hash值換算出來(lái)的數(shù)組下標(biāo)位置已經(jīng)存在值)

? ? ?最少12個(gè)元素嚣镜,最多27個(gè)元素? ?12+15個(gè)

19. hashMap(1.8) 擴(kuò)容的條件是什么爬迟?

? ? ? ?數(shù)據(jù)結(jié)構(gòu):數(shù)組 + ( 鏈表 or 紅黑樹(shù) )?

???????擴(kuò)容必須滿足條件:

? ? ? ?1、 存放新值的時(shí)候當(dāng)前已有元素的個(gè)數(shù)必須大于閾值

? ? ?當(dāng)?shù)?3個(gè)元素進(jìn)來(lái)時(shí)菊匿,發(fā)生擴(kuò)容

20. hashMap(1.8)源碼字段分析 ?

//默認(rèn)table數(shù)組buckets的數(shù)目付呕,必須是2的平方,默認(rèn)值是16??

static?final?int?DEFAULT_INITIAL_CAPACITY?=?1?<<?4;? ?

//默認(rèn)table最大的長(zhǎng)度約10億多(1073741824)最大的buckets數(shù)目??

static?final?int?MAXIMUM_CAPACITY?=?1?<<?30;??

//默認(rèn)負(fù)載因子??

static?final?float?DEFAULT_LOAD_FACTOR?=?0.75f;??

//當(dāng)單個(gè)鏈表的個(gè)數(shù)超過(guò)8個(gè)節(jié)點(diǎn)就轉(zhuǎn)化為紅黑樹(shù)存儲(chǔ)??

static?final?int?TREEIFY_THRESHOLD?=?8;??

//如果原來(lái)是紅黑樹(shù)跌捆,后來(lái)被刪除一些節(jié)點(diǎn)后徽职,只剩小于等于6個(gè),會(huì)被重新轉(zhuǎn)成鏈表存儲(chǔ)??

static?final?int?UNTREEIFY_THRESHOLD?=?6;??

//當(dāng)數(shù)組的長(zhǎng)度(注意不是map的size而是table.length)大于64的時(shí)候佩厚,??

//會(huì)對(duì)單個(gè)桶里大于8的鏈表進(jìn)行樹(shù)化??

static?final?int?MIN_TREEIFY_CAPACITY?=?64;??

//用來(lái)實(shí)現(xiàn)遍歷map的set,依次遍歷table中所有桶中的node或者treeNode??

transient?Set<Map.Entry<K,V>>?entrySet;??

//當(dāng)前存儲(chǔ)的實(shí)際數(shù)據(jù)量=map.size而不是table.length??

transient?int?size;??

//修改次數(shù)姆钉,用來(lái)判斷是否該map同時(shí)被多個(gè)線程操作,??

//多線程環(huán)境下會(huì)拋出異常ConcurrentModificationException??

transient?int?modCount;??

//當(dāng)前數(shù)組中的閾值?table.length?*?loadFactor抄瓦,如果超 過(guò)這個(gè)閾值潮瓶,就要進(jìn)行擴(kuò)容?(resize)??

int?threshold;??

//負(fù)載因子??

final?float?loadFactor;??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闺鲸,隨后出現(xiàn)的幾起案子筋讨,更是在濱河造成了極大的恐慌,老刑警劉巖摸恍,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悉罕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡立镶,警方通過(guò)查閱死者的電腦和手機(jī)壁袄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)媚媒,“玉大人嗜逻,你說(shuō)我怎么就攤上這事$哉伲” “怎么了栈顷?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵逆日,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我萄凤,道長(zhǎng)室抽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任靡努,我火速辦了婚禮坪圾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惑朦。我一直安慰自己兽泄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布漾月。 她就那樣靜靜地躺著病梢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栅屏。 梳的紋絲不亂的頭發(fā)上飘千,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音栈雳,去河邊找鬼护奈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哥纫,可吹牛的內(nèi)容都是我干的霉旗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蛀骇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厌秒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起擅憔,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸵闪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后暑诸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蚌讼,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年个榕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了篡石。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡西采,死狀恐怖凰萨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤胖眷,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布武通,位于F島的核電站,受9級(jí)特大地震影響珊搀,放射性物質(zhì)發(fā)生泄漏厅须。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一食棕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧错沽,春花似錦簿晓、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至放可,卻和暖如春谒臼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耀里。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蜈缤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冯挎。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓底哥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親房官。 傳聞我的和親對(duì)象是個(gè)殘疾皇子趾徽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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

  • Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底...
    Java面試指南閱讀 563評(píng)論 0 2
  • Java SE 基礎(chǔ): 封裝、繼承翰守、多態(tài) 封裝: 概念:就是把對(duì)象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體孵奶,并盡...
    Jayden_Cao閱讀 2,110評(píng)論 0 8
  • ArrayList實(shí)現(xiàn)原理要點(diǎn)概括 參考文獻(xiàn):http://zhangshixi.iteye.com/blog/6...
    晨光光閱讀 1,068評(píng)論 0 1
  • 臭臭壞還在睡覺(jué),他是一只瞌睡蟲(chóng)蜡峰,睡不醒的瞌睡蟲(chóng)了袁。看著他睡得很香事示,日子也變得越來(lái)越美了早像。 還有兩天了…… 明天后天,...
    紅豆小妮閱讀 376評(píng)論 0 1
  • 漂亮的漂移~完美的過(guò)彎~驚艷的內(nèi)道超車....風(fēng)肖爵,極速的掠過(guò)臉頰.…已42秒的成績(jī)完賽啦B小!!嗯嗯冀自,很滿意揉稚! --...
    王宇_ebc2閱讀 204評(píng)論 0 0