關於集合中一些常考的知識點總結

本章主要總結了集合的一些基礎但有重點的知識點,例如他們的底層數據結構以及集合之間的區別,其中 HashMap 最爲重點。面試

集合

Java的集合框架中能夠分爲兩大類:第一類是按照單個元素存儲的 Collection 集合,其中 Set, List, Queue 都實現了 Collection 接口。第二類是按照 Key-Value 存儲的 Map 集合。數組

List

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

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

Set 是一種不容許出現重複元素的集合類型,經常使用的三個實現類是 HashSet、TreeSet 和 LinkedHashSet。

(1)、HashSet

HashSet 其實是用 HashMap 來實現的,如圖

只是 Value 被固定爲一個靜態對象

使用 Key 來保證集合元素的惟一性,不過它不保證集合元素的順序。

(2)、TreeSet

TreeSet 也是用 TreeMap 來實現的,底層爲樹結構,TreeSet 則可以保證集合元素是有序的。

(3)、LinkedHashSet

LinkedHashSet 繼承 HashSet,具備 HashSet 優勢,不過與 HashSet 不一樣的是,LinkedHashSet 內部使用了鏈表來維護元素的插入順序。

這些知識點若是都能本身打開源碼配合看一下,不少有關集合的面試題就能夠應付了。

最後推廣下個人公衆號:苦逼的碼農戳我便可關注,文章都會首發於個人公衆號,期待各路英雄的關注交流。

相關文章
相關標籤/搜索