本章主要總結了集合的一些基礎但有重點的知識點,例如他們的底層數據結構以及集合之間的區別,其中 HashMap 最爲重點。面試
Java的集合框架中能夠分爲兩大類:第一類是按照單個元素存儲的 Collection 集合,其中 Set, List, Queue 都實現了 Collection 接口。第二類是按照 Key-Value 存儲的 Map 集合。數組
List常量的兩個子類分別是 ArrayList 和 LinkedList 這兩個集合。安全
(1)、ArrayList 的特色。數據結構
A. ArrayList 底層數據結構是數組,數組的特色就是能夠快速隨機訪問,直接根據下標定位,缺點是插入和刪除速度比較慢,須要移動元素。多線程
B. ArrayList 每次擴容以後的大小爲以前的 1.5 倍。默認初始容量大小爲 10。框架
(2)、LinkedList 的特色性能
LinkedList 底層數據結構是雙向鏈表,鏈表的特色就是隨機訪問速度慢,必須一個一個遍歷,不能直接經過下標定位,不過在插入、刪除方面速度就比較快。不過因爲鏈表是內存分配不要求連續,內存的利用率比較高。.net
LinkedList 還實現了另一個接口Deque,即 double-ended queue,使得 LinkedList 同時具備隊列和棧的特性。線程
(3)、vector 的特色code
vector 和 ArrayList 基本同樣,不過 Vector 是線程安全的,而 ArrayList 是線程不安全的,
ArrayList 和 LinkedList 都是線程不安全的集合。
Map 是一種 key-value 的集合,其經常使用的集合實現類有 HashMap, HashTable, TreeMap。
(1)、HashMap(重重點)
HashMap 的底層數據結構是 鏈表 + 數組,若是對他的底層結構不大懂的能夠看我以前寫的一篇文章:HashMap的存取原理你知道多少
HashMap 在進行 put 操做時,容許 key 和 value 爲 null,且是線程不安全的,因此 HashMap 的性能很是好,只不過在多線程的環境下使用,須要給他加上對應的鎖
重點數據:HashMap 的默認容量爲 capacity = 16, 默認擴容因子 loadFactor = 0.75,至於擴容因子有什麼用,下面會涉及到。
不過須要注意的是,HashMap 內部用變量 threshold 變量來表示 HashMap 中能放入的元素個數,且在 threshold 不超過最大值前提下, threshold = loadFactor * capacity。
也就是說,當元素的個數達到 threshold 以後,就會觸發 HashMap 的擴容,而不是達到 capacity 才觸發擴容。每次擴容以後的容量爲以前的 2 倍。
而 ArrayList 則是元素達到 capacity 時才觸發擴容。
還有一個須要注意的是,HashMap 容量並不會在 new 的時候分配,而是在第一次 put 的時候才完成建立的。
public V put(K key, V value){ if(table == EMPTY_TABLE){ // 初始化 inflateTable(threshold); } }
默認初始化容量大小 capacity = 16,若是咱們在初始化的時候指定了容量的大小 initialCapacity,則會先計算出比 initialCapacity 大的 2 的冪存入 threshold,而且也會把初始化容量置爲 capacity = threshold。例如當咱們指定初始容量 initialCapacity = 26 的話,則 threshold = 32, capacity = 32。
(2)、HashTable的特色
a. HashTable 和 HashMap 在工做原理上幾乎同樣,不過 HashTable 是線程安全的,如圖
不過鎖是直接加在方法外面,因此在多線程環境下,性能極差。
不過在多線程的環境下,咱們優先使用 ConcurrentHashMap 集合,這個集合在工做原理上也幾乎和前面兩個同樣,但它是線程安全的,而且不像 HashTable 那樣,把整個方法都給加鎖了,而是把方法裏面的關鍵代碼加鎖了,如圖:
因此在處理速度上比較快。
b. HashTable 不容許 key 和 value 爲 null。
c. HashMap 的迭代器是 fail-fast 機制(快速失敗機制), 而 HashTable 則是 fail-safe 機制(快速安全),若是不知道 fail-fast 與 fail-safe 的,能夠看我以前寫 的一篇文章:談談fail-fast與fail-safe
(3)、LinkedHashMap 的特色
LinkedHashMap 是 HashMap 的一個子類,咱們知道 HashMap是在插入的時候是根據哈希碼來選擇位置的,是無序的,而 LinkedHashMap 在插入的時候具備雙向鏈表的特性,內部使用鏈表維護了插入的順序,可以保證輸出的順序和輸入時的相同。
LinkedHashMap 也是線程不安全的,而且容許 key-value 爲 null。
(4)、TreeMap
TreesMap 的底層數據結構是紅黑樹,和 HashMap 不一樣,它的 get, put, remove 操做都是 O(logn) 的時間複雜度,而且元素是有序的。
一樣,TreeMap 也是線程不安全的。
Set 是一種不容許出現重複元素的集合類型,經常使用的三個實現類是 HashSet、TreeSet 和 LinkedHashSet。
(1)、HashSet
HashSet 其實是用 HashMap 來實現的,如圖
只是 Value 被固定爲一個靜態對象
使用 Key 來保證集合元素的惟一性,不過它不保證集合元素的順序。
(2)、TreeSet
TreeSet 也是用 TreeMap 來實現的,底層爲樹結構,TreeSet 則可以保證集合元素是有序的。
(3)、LinkedHashSet
LinkedHashSet 繼承 HashSet,具備 HashSet 優勢,不過與 HashSet 不一樣的是,LinkedHashSet 內部使用了鏈表來維護元素的插入順序。
這些知識點若是都能本身打開源碼配合看一下,不少有關集合的面試題就能夠應付了。
最後推廣下個人公衆號:苦逼的碼農:戳我便可關注,文章都會首發於個人公衆號,期待各路英雄的關注交流。