集合總結

一跺撼、集合的分類


關系結構圖


二、線程安全性

List:vector

Set:谷歌的guava其實已經(jīng)實現(xiàn)了線程安全的ConcurrentHashSet

Map:HashTable和ConcurrentHashMap

重點:線程安全的集合效率會比線程不安全的集合低邓萨,所以在單線程時優(yōu)先考慮線程不安全的集合,要的是工作效率,但是多線程時需要考慮到安全性這時盡量采用線程安全的集合次泽。

三变秦、小知識點總結

①成榜、 Collection 和 Collections 有什么區(qū)別?


②蹦玫、List赎婚、Set刘绣、Map 之間的區(qū)別是什么?


③挣输、HashMap是無序的纬凤,但如果你要對一個 key 集合進行有序的遍歷,那 TreeMap 是更好的選擇撩嚼。

④停士、如何解決Hash沖突問題?

當計算出的 hash 值相同時完丽,我們稱之為 hash 沖突恋技,HashMap 的做法是用鏈表和紅黑樹存儲相同 hash 值的 value。當 hash 沖突的個數(shù)比較少時舰涌,使用鏈表否則使用紅黑樹猖任。

⑤、關于容量和擴容

JDK1.7之前——單列集合的初始容量是10瓷耙,雙列集合是16朱躺;

JDK1.8之后——初始默認容量是0;

擴容——ArrayList 和 Vector 都會根據(jù)實際的需要動態(tài)的調整容量搁痛,只不過在 Vector 擴容每次會增加 1 倍长搀,而 ArrayList 只會增加 50%。

⑥鸡典、數(shù)據(jù)結構中的什么是數(shù)組源请?什么是鏈表?

所謂數(shù)組彻况,是相同數(shù)據(jù)類型的元素按一定順序排列的集合

數(shù)組:存儲區(qū)間是連續(xù)的谁尸,占用內存嚴重,故空間復雜的很大纽甘。但數(shù)組的二分查找時間復雜度小良蛮,為O(1);數(shù)組的特點是:尋址容易悍赢,插入和刪除困難决瞳;

所謂鏈表,鏈表是一種物理存儲單元上非連續(xù)左权、非順序的存儲結構皮胡,數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序實現(xiàn)的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成赏迟,結點可以在運行時動態(tài)生成屡贺。每個結點包括兩個部分:一個是存儲數(shù)據(jù)元素的數(shù)據(jù)域,另一個是存儲下一個結點地址的指針域。 相比于線性表順序結構烹笔,操作復雜裳扯。由于不必須按順序存儲,鏈表在插入的時候可以達到O(1)的復雜度谤职,比另一種線性表順序表快得多饰豺,但是查找一個節(jié)點或者訪問特定編號的節(jié)點則需要O(n)的時間,而線性表和順序表相應的時間復雜度分別是O(logn)和O(1)允蜈。

鏈表:鏈表存儲區(qū)間離散冤吨,占用內存比較寬松,故空間復雜度很小饶套,但時間復雜度很大漩蟆,達O(N)。鏈表的特點是:尋址困難妓蛮,插入和刪除容易怠李。

⑦、什么是哈希表蛤克?

從問題⑥中可以看到數(shù)組和鏈表各有優(yōu)缺點捺癞,那么我們能不能綜合兩者的特性,做出一種尋址容易构挤,插入刪除也容易的數(shù)據(jù)結構髓介?答案是肯定的,這就是我們要提起的哈希表筋现。哈希表的結構是鏈表+數(shù)組的組合形式唐础,哈希表((Hash table)既滿足了數(shù)據(jù)的查找方便,同時不占用太多的內容空間矾飞,使用也十分方便一膨。

⑧、Set 里的元素是不能重復的,那么用什么方法來區(qū)分重復與否呢?是用==還是equals()?它們有何區(qū)別?

equals 方法(是String類從它的超類Object中繼承的)被用來檢測兩個對象是否相等洒沦,即兩個對象的內容是否相等豹绪。

==用于比較引用和比較基本數(shù)據(jù)類型時具有不同的功能:

比較基本數(shù)據(jù)類型,如果兩個值相同微谓,則結果為true

而在比較引用時,如果引用指向內存中的同一對象输钩,結果為true

在比較Set中的元素時豺型,先比較hashCode是否相同,如果不同則肯定不是同一對象买乃,如果相同再比較值姻氨,值也相同則為同一對象

⑨、HashMap的工作原理

HashMap是基于hashing的原理剪验,我們使用put(key, value)存儲對象到HashMap中肴焊,使用get(key)從HashMap中獲取對象前联。當我們給put()方法傳遞鍵和值時,我們先對鍵調用hashCode()方法娶眷,返回的hashCode用于找到bucket位置來儲存Entry對象似嗤。”這里關鍵點在于指出届宠,HashMap是在bucket中儲存鍵對象和值對象烁落,作為Map.Entry。這一點有助于理解獲取對象的邏輯豌注。如果你沒有意識到這一點伤塌,或者錯誤的認為僅僅只在bucket中存儲值的話,你將不會回答如何從HashMap中獲取對象的邏輯轧铁。這個答案相當?shù)恼_每聪,也顯示出面試者確實知道hashing以及HashMap的工作原理。但是這僅僅是故事的開始齿风,當面試官加入一些Java程序員每天要碰到的實際場景的時候药薯,錯誤的答案頻現(xiàn)。下個問題可能是關于HashMap中的碰撞探測(collision detection)以及碰撞的解決方法:

“當兩個對象的hashcode相同會發(fā)生什么聂宾?” 從這里開始果善,真正的困惑開始了,一些面試者會回答因為hashcode相同系谐,所以兩個對象是相等的巾陕,HashMap將會拋出異常,或者不會存儲它們纪他。然后面試官可能會提醒他們有equals()和hashCode()兩個方法鄙煤,并告訴他們兩個對象就算hashcode相同,但是它們可能并不相等茶袒。一些面試者可能就此放棄梯刚,而另外一些還能繼續(xù)挺進,他們回答“因為hashcode相同薪寓,所以它們的bucket位置相同亡资,‘碰撞’會發(fā)生。因為HashMap使用鏈表存儲對象向叉,這個Entry(包含有鍵值對的Map.Entry對象)會存儲在鏈表中锥腻。”這個答案非常的合理母谎,雖然有很多種處理碰撞的方法瘦黑,這種方法是最簡單的,也正是HashMap的處理方法。但故事還沒有完結幸斥,面試官會繼續(xù)問:

“如果兩個鍵的hashcode相同匹摇,你如何獲取值對象?” 面試者會回答:當我們調用get()方法甲葬,HashMap會使用鍵對象的hashcode找到bucket位置廊勃,然后獲取值對象。面試官提醒他如果有兩個值對象儲存在同一個bucket演顾,他給出答案:將會遍歷鏈表直到找到值對象供搀。面試官會問因為你并沒有值對象去比較,你是如何確定確定找到值對象的钠至?除非面試者直到HashMap在鏈表中存儲的是鍵值對葛虐,否則他們不可能回答出這一題。

其中一些記得這個重要知識點的面試者會說棉钧,找到bucket位置之后屿脐,會調用keys.equals()方法去找到鏈表中正確的節(jié)點,最終找到要找的值對象宪卿。完美的答案的诵!

許多情況下,面試者會在這個環(huán)節(jié)中出錯佑钾,因為他們混淆了hashCode()和equals()方法西疤。因為在此之前hashCode()屢屢出現(xiàn),而equals()方法僅僅在獲取值對象的時候才出現(xiàn)休溶。一些優(yōu)秀的開發(fā)者會指出使用不可變的代赁、聲明作final的對象,并且采用合適的equals()和hashCode()方法的話兽掰,將會減少碰撞的發(fā)生芭碍,提高效率。不可變性使得能夠緩存不同鍵的hashcode孽尽,這將提高整個獲取對象的速度窖壕,使用String,Interger這樣的wrapper類作為鍵是非常好的選擇杉女。

如果你認為到這里已經(jīng)完結了瞻讽,那么聽到下面這個問題的時候,你會大吃一驚熏挎∷儆拢“如果HashMap的大小超過了負載因子(load factor)定義的容量,怎么辦婆瓜?”除非你真正知道HashMap的工作原理快集,否則你將回答不出這道題。默認的負載因子大小為0.75廉白,也就是說个初,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣猴蹂,將會創(chuàng)建原來HashMap大小的兩倍的bucket數(shù)組院溺,來重新調整map的大小,并將原來的對象放入新的bucket數(shù)組中磅轻。這個過程叫作rehashing珍逸,因為它調用hash方法找到新的bucket位置。

如果你能夠回答這道問題聋溜,下面的問題來了:“你了解重新調整HashMap大小存在什么問題嗎谆膳?”你可能回答不上來,這時面試官會提醒你當多線程的情況下撮躁,可能產生條件競爭(race condition)漱病。

當重新調整HashMap大小的時候,確實存在條件競爭把曼,因為如果兩個線程都發(fā)現(xiàn)HashMap需要重新調整大小了杨帽,它們會同時試著調整大小。在調整大小的過程中嗤军,存儲在鏈表中的元素的次序會反過來注盈,因為移動到新的bucket位置的時候,HashMap并不會將元素放在鏈表的尾部叙赚,而是放在頭部老客,這是為了避免尾部遍歷(tail traversing)。如果條件競爭發(fā)生了纠俭,那么就死循環(huán)了沿量。這個時候,你可以質問面試官冤荆,為什么這么奇怪朴则,要在多線程的環(huán)境下使用HashMap呢?:)

熱心的讀者貢獻了更多的關于HashMap的問題:

為什么String, Interger這樣的wrapper類適合作為鍵钓简? String, Interger這樣的wrapper類作為HashMap的鍵是再適合不過了乌妒,而且String最為常用。因為String是不可變的外邓,也是final的撤蚊,而且已經(jīng)重寫了equals()和hashCode()方法了。其他的wrapper類也有這個特點损话。不可變性是必要的侦啸,因為為了要計算hashCode()槽唾,就要防止鍵值改變,如果鍵值在放入時和獲取時返回不同的hashcode的話光涂,那么就不能從HashMap中找到你想要的對象庞萍。不可變性還有其他的優(yōu)點如線程安全。如果你可以僅僅通過將某個field聲明成final就能保證hashCode是不變的忘闻,那么請這么做吧钝计。因為獲取對象的時候要用到equals()和hashCode()方法,那么鍵對象正確的重寫這兩個方法是非常重要的齐佳。如果兩個不相等的對象返回不同的hashcode的話私恬,那么碰撞的幾率就會小些,這樣就能提高HashMap的性能炼吴。

我們可以使用自定義的對象作為鍵嗎本鸣? 這是前一個問題的延伸。當然你可能使用任何對象作為鍵硅蹦,只要它遵守了equals()和hashCode()方法的定義規(guī)則永高,并且當對象插入到Map中之后將不會再改變了。如果這個自定義對象時不可變的提针,那么它已經(jīng)滿足了作為鍵的條件命爬,因為當它創(chuàng)建之后就已經(jīng)不能改變了。

我們可以使用CocurrentHashMap來代替Hashtable嗎辐脖?這是另外一個很熱門的面試題饲宛,因為ConcurrentHashMap越來越多人用了。我們知道Hashtable是synchronized的嗜价,但是ConcurrentHashMap同步性能更好艇抠,因為它僅僅根據(jù)同步級別對map的一部分進行上鎖。ConcurrentHashMap當然可以代替HashTable久锥,但是HashTable提供更強的線程安全性家淤。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瑟由,隨后出現(xiàn)的幾起案子絮重,更是在濱河造成了極大的恐慌,老刑警劉巖歹苦,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件青伤,死亡現(xiàn)場離奇詭異,居然都是意外死亡殴瘦,警方通過查閱死者的電腦和手機狠角,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚪腋,“玉大人丰歌,你說我怎么就攤上這事姨蟋。” “怎么了立帖?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵芬探,是天一觀的道長。 經(jīng)常有香客問我厘惦,道長,這世上最難降的妖魔是什么哩簿? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任宵蕉,我火速辦了婚禮,結果婚禮上节榜,老公的妹妹穿的比我還像新娘羡玛。我一直安慰自己,他們只是感情好宗苍,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布稼稿。 她就那樣靜靜地躺著,像睡著了一般讳窟。 火紅的嫁衣襯著肌膚如雪让歼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天丽啡,我揣著相機與錄音谋右,去河邊找鬼。 笑死补箍,一個胖子當著我的面吹牛改执,可吹牛的內容都是我干的。 我是一名探鬼主播坑雅,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼辈挂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裹粤?” 一聲冷哼從身側響起终蒂,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遥诉,沒想到半個月后后豫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡突那,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年挫酿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愕难。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡早龟,死狀恐怖惫霸,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情葱弟,我是刑警寧澤壹店,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站芝加,受9級特大地震影響硅卢,放射性物質發(fā)生泄漏。R本人自食惡果不足惜藏杖,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一将塑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝌麸,春花似錦点寥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弟疆,卻和暖如春戚长,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怠苔。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工历葛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘀略。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓恤溶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親帜羊。 傳聞我的和親對象是個殘疾皇子咒程,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內容