集合總結

集合



常用集合關系圖


各種集合的區別

集合分為單列集合和雙列集合兩種:

一.單列集合:

Collection的結構圖

Collection是單列集合的頂級接口:

其中有三類集合:

1.List(ArrayList,LinkedList,Vector等)

有序的可以重復的集合,JDK1.6和JDK1.7的時候創建集合時初始容量是10,而JDK1.8中默認容量是0,首次添加元素不超過10時,容量變為10。

List的加載因子系數<=1,即當元素個數超過(容器長度*加載因子系數)時,進行擴容

①ArrayList集合是動態數組的數據結構實現的,它的隨機訪問和遍歷的效率比較高,在需要頻繁的讀取集合中的元素的時候,推薦使用ArrayList,但是增刪操作要影響數組內的其他數據的下標,所以增刪操作的效率比較慢。

ArrayList每次擴增容量為原本的1.5倍,JDK1.8之后算法為oldCapacity+(oldCapacity >>1)。

ArrayList的擴容上限約21億,int的最大值。

②LinkedList集合是雙向的鏈表的數據結構實現,沒有下標,通過鏈來連接數據,在非首尾的增加和刪除操作時,LinkedList比ArrayList的效率要高,推薦使用LinkedList,但是查詢的時候,每次都要從首位移動指針往后依次查找,所以查詢的效率比較慢。

③Vector集合與ArrayList集合類似,內部都是維護一個數組,只不過前者在方法上加上了synchronized關鍵字、線程安全、效率低,后者線程不安全,但是效率高。

Vector每次擴增容量為原來的兩倍。

2.Set(HashSet等)

除了TreeSet集合外元素無序,不允許元素重復。

Set的擴容量為原來的2倍,加載因子為0.75。

①HashSet集合是基于HashMap實現的,HashSet底層使用HashMap來保存元素,HashMap是數組和鏈表的數據結構(下面HashMap具體介紹),HashSet和HashMap的初始容量都是16

3.Queue/Deque

①Queue隊列,隊列是一種特殊的線性表,它只允許在表的前端進行刪除操作,而在表的后端進行插入操作,LinkedList類實現了Queue接口,可以吧LinkedList當成Queue來用

②Deque雙端隊列,可以在兩端進行插入和刪除操作

二.雙列集合:

Map的結構示意圖

1.Map(HashMap,Hashtable等)

①HashMap集合線程非安全,使用鍵值對(key-value)的方式存儲數據,允許key和value為null,鍵(key)不能重復,值(value)可以重復,它和HashSet是基于哈希表的鏈表散列的數據結構,即底層是數組和鏈表(模擬指針)實現的,到了JDK1.8后變成了數組+鏈表+紅黑樹。

HashMap底層是通過一個transient(防止反序列化) Node[]table node數組實現的,接下來單個Node數據類型:是HanshMap靜態內部類。靜態內部類中有一個成員變量:

Node<K,V>next;

?通過該成員變量,其實底層用的是單向鏈表,性能低


HashMap的結構示意圖


HashMap的執行流程


HashMap 基于 Hash 算法實現的,我們通過 put(key,value)存儲,get(key)來獲取。當傳入 key 時,HashMap 會根據 key. hashCode() 計算出 hash 值,根據 hash 值將 value 保存在 bucket 里。當計算出的 hash 值相同時并且equals比較的值不同時,我們稱之為 hash 沖突,HashMap 的做法是用鏈表和紅黑樹存儲相同 hash 值的 value。當 hash 沖突的個數比較少時,使用鏈表否則使用紅黑樹。

在向HashMap中添加數據的時候,會先調用hashCode方法計算并比較hash值,當hash相同的情況在調用equals方法比較,當兩個均不相同時判定集合中不存在,然后將數據插入到集合中。兩個對象的hash值相同,但是不一定是同一個對象,也就是說自身的值可能會不相同。

(例如:String a ="通話";String b="重地";這兩個字符串生成的hash值同為1179395,但是其自身的值卻不相同)


HashMap和Entry的關系

從圖中可以看出:?

1)HashMap繼承于AbstractMap類,實現了Map接口。Map是"key-value鍵值對"接口,AbstractMap實現了"鍵值對"的通用函數接口。?

2)HashMap是通過"拉鏈法"實現的哈希表。它包括幾個重要的成員變量:table,?size,?threshold,?loadFactor,?modCount。

table是一個Entry[]數組類型,而Entry實際上就是一個單向鏈表。哈希表的"key-value鍵值對"都是存儲在Entry數組中的。

size是HashMap的大小,它是HashMap保存的鍵值對的數量。?

threshold是HashMap的閾值,用于判斷是否需要調整HashMap的容量。threshold的值="容量*加載因子",當HashMap中存儲數據的數量達到threshold時,就需要將HashMap的容量加倍。

loadFactor就是加載因子。?

modCount是用來實現fail-fast機制的。

LinkedHashMap:底層也是一個Entry<k,v>數組,接下來單個Entry數據類型

Entry<K,V>before,after;

②Hashtable線程安全,是線程安全的,但是其同步鎖是全局鎖,效率很低,所以Hashtable現在是保留類不建議使用。

單線程的情況下HashMap效率高,推薦使用;多線程的情況下可以使用java.util.concurrent包下的ConcurrentHashMap替代,它之前采用Segment方式的分段同步鎖,將所有的數據分割成幾部分的數據區域,一個區域一把鎖,訪問不同區域時不會收到影響,JDK1.8版本之后采用優化后的synchronized,將每一個數據分別鎖住,不同數據間的訪問不會收到影響,效率大大增加,并且線程是安全的,多線程并發情況下很推薦使用!

雙列集合的五種遍歷方式

1)通過map.keySey();獲取所有的key的Set集合,然后可以通過增強for自動迭代,也可以獲取迭代器iterator然后用while循環進行手動遍歷

2)通過map.values();獲得所有的value的集合,返回值為Collecton,然后用增強for自動迭代

3)(推薦)通過map.entrySet();獲取所有的鍵值對的Set集合,Set集合中保存的是每一個鍵值對(Map.Entry),然后可以通過增強for自動迭代,也可以獲取迭代器iterator然后用while循環進行手動遍歷

三.關于迭代器

迭代器是Iterator接口:該接口中有三個核心方法 ,維護指針可以向下移動(next),移動到指定位置后,取出當前位置的元素(next),以及重置指針操作(remove)。

為什么數組和集合可以使用for循環進行迭代遍歷?

解析:所有的數組和集合都實現了Iterable接口,Iterable接口中只有一個方法,iterator方法返回值類型是Iterator類型,我們將思路轉到Iterator,我們發現該接口三個方法。hasNext,next和remove,最主要的是hasNext和next。他們在底層幫我們去維護的可以被迭代數組或者集合的迭代策略。

四.JDK版本差異更新

排序算法

線程安全的集合

集合擴容的算法

五.集合在特定場景下的應用方案

最近瀏覽可以選取LinkedList

先進先出可以考慮Queue隊列

先進后出可以考慮Stack,遞歸,壓棧 ,彈棧?

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容

  • Java集合類主要有2大分支,Collection及Map。Collection體系如下: Map體系如下: **...
    Huang遠閱讀 395評論 0 0
  • 剖析面試最常見問題之Java集合 1.說說list、set和map的區別? ???1.list是有序可重復; ??...
    血武行者閱讀 329評論 0 0
  • Java集合類可用于存儲數量不等的對象,并可以實現常用的數據結構如棧,隊列等,Java集合還可以用于保存具有映射關...
    小徐andorid閱讀 1,957評論 0 13
  • 經過十一篇文章的分析,終于把一些主要的集合類的實現原理分析完了。本文,我們將對之前分析的知識點做一次總結。 集合框...
    swz_android閱讀 961評論 0 1
  • 躺在向日葵花海上的飛毯 隨風搖曳 空氣中彌漫著陽光和花海的氣息 那味道被蒸發出來了 仿佛都能被看見、被摸到 天空的...
    三石與三心閱讀 122評論 0 0