Java集合學習總結

weixin_33895657發表於2018-03-08

集合的根介面:Collection和 Map

Collection介面的常用子介面:List, Set

List介面的常用實現類:ArrayList, LinkedList, Stack, Vector

Set介面的常用實現類:HashSet, TreeSet

Map介面的常用實現類:HashMap, Hashtable, TreeMap

一、ArrayList

1. ArrayList允許包括 null 在內的所有元素。

2. ArrayList是有序的,因為ArrayList的大小可變是通過陣列實現的。陣列的資料結構是順序表(線性表的一種),即記憶體中連續的一塊儲存空間,順序和實體地址相同,這樣只要確定了儲存線性表的起始位置,線性表中任一資料元素都可以隨機存取,所以線性表的順序儲存結構是一種隨機存取的儲存結構。

新增的演算法:

一般情況下,在第i ( 1 ≤ i ≤ n)個元素之前插入一個元素時,需要將n至第i(共n-i+1)個元素向後移動一個位置。

刪除的演算法:

一般情況下,刪除第i ( 1 ≤ i ≤ n)個元素時,需將從第i+1至第n(共n-i)個元素依此向前移動一個位置。

3. ArrayList中的元素可以重複。

4. 在新增大量元素前,應用程式可以使用 ensureCapacity(int minCapacity) 方法操作來增加 ArrayList 例項的容量。這可以減少遞增式再分配的數量。因為

int newCapacity = (oldCapacity * 3)/2 + 1; //每次只擴充套件1.5陪,當list新增大量資料就要多次執行這個複製陣列的操作

if (newCapacity < minCapacity)

newCapacity = minCapacity;

//通過對陣列的不斷複製達到List長度的可變

elementData = Arrays.copyOf(elementData, newCapacity);

5. 此實現不是同步的(也就是非執行緒安全的)。如果多個執行緒同時訪問一個 ArrayList 例項,而其中至少一個執行緒從結構上修改了列表,那麼它必須 保持外部同步。(結構上的修改是指任何新增或刪除一個或多個元素的操作,或者顯式調整底層陣列的大小;僅僅設定元素的值不是結構上的修改。)這一般通過對自然封裝該列表的物件進行同步操作來完成。如果不存在這樣的物件,則應該使用 Collections.synchronizedList 方法將該列表“包裝”起來。這最好在建立時完成,以防止意外對列表進行不同步的訪問: List list = Collections.synchronizedList(new ArrayList(...));

二、 Vector

Vector和ArrayList是相同的,不同是Vector是執行緒安全的,同時也帶來同步操作也花費大量的時間。同樣是有序,可以有重複元素

三、 LinkedList

  1. 允許包括 null 在內的所有元素。

  2. LinkedList是有序的,LinkedList的資料結構是雙向連結串列(線性表的一種),儲存單元是任意的,可以連續,也可以不連續。雙向連結串列的線性結構依靠節點前後的指標域來維護。因此在元素查詢時效率比較低,因為要從頭開始遍歷每一個元素的指標域(指標域指向他的直接前驅和後繼,或者說指標域中儲存著直接前驅和後繼的地址)去確定查詢的元素。但是,雙向連結串列的插入和刪除操作效率比較高。

雙向連結串列中插入節點:

5838771-bb7131b379e0ca39.png

雙向連結串列刪除節點:

5838771-da2ef3d67ff62a60.png
  1. LinkedList中的元素可以重複。

  2. 此實現不是同步的(也就是非執行緒安全的)。

四、 Stack

  1. 棧的資料結構介紹
    棧是限定僅在表尾插入或刪除操作的線性表。表尾端叫做棧頂,表頭端叫做棧底。棧又稱為後進先出(Last Into First Out),簡稱LIFO結構。

  2. stack通過五個操作對類 Vector 進行了擴充套件,是Vector的子類。

5838771-86e55de2e1f469a1.png

Set介面:一個不包含重複元素的 collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。

雜湊表(Hash table,也叫雜湊表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。

給定表M,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的地址,則稱表M為雜湊(Hash)表,函式f(key)為雜湊(Hash) 函式

  • 若結構中存在關鍵字和K相等的記錄,則必定儲存在f(K)的位置上。由此,不需比較便可直接取得所查記錄。這個對應關係f稱為雜湊函式(Hash function),按這個思想建立的表為雜湊表。

  • 對不同的關鍵字可能得到同一雜湊地址,即key1≠key2,而f(key1)=f(key2),這種現象稱衝突。具有相同函式值的關鍵字對該雜湊函式來說稱做同義詞。

  • 綜上所述,根據雜湊函式H(key)和處理衝突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的“象”, 作為這條記錄在表中的儲存位置,這種表便稱為雜湊表,這一映象過程稱為雜湊造表或雜湊,所得的儲存位置稱雜湊地址。這個現象也叫雜湊桶,在雜湊桶中,只能通過順序的方式來查詢,一般只需要查詢三次就可以找到。科學家計算過,當負載因子(load factor)(也叫裝填因子)不超過75%,查詢效率最高。因此再雜湊的條件也是當裝填因子大於0.75。

5838771-37d023d2e0adfbf8.png

這是一個連結串列陣列,陣列的每一個元素是一個連結串列的hashcode。當產生衝突,採用再雜湊法,即在同義詞產生地址衝突時計算另一個雜湊函式地址,直到衝突不再發生,這種方法不易產生“聚集”,但增加了計算時間。再雜湊如果雜湊表太滿就要建立一個桶數量更多的表,並將所有元素插入到這個新表中,然後丟棄原來的表。

五、 HashSet

此類實現 Set 介面,由雜湊表(實際上是一個 HashMap 例項)支援。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。

  1. HashSet無序。

  2. HashSet中元素不能重複,如果add()兩個相同的元素,只儲存一個。

  3. HashSet是非執行緒安全的。

  4. 如果迭代效能很重要,則不要將初始容量(桶數量)設定得太高(或將載入因子設定得太低)。

六、 TreeSet

  1. TreeSet是有序的,順序是自然順序,是自動完成排序的。

  2. TreeSet中元素不可以重複,如果新增兩個相同的元素,只保留一個。

  3. TreeSet非執行緒安全的

七、HashMap

基於雜湊表的 Map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證對映的順序,特別是它不保證該順序恆久不變。

  1. 如果迭代效能很重要,則不要將初始容量設定得太高(或將載入因子設定得太低)。

  2. HashMap 的例項有兩個引數影響其效能:初始容量 和載入因子。容量 是雜湊表中桶的數量,初始容量只是雜湊表在建立時的容量。載入因子 是雜湊表在其容量自動增加之前可以達到多滿的一種尺度。當雜湊表中的條目數超出了載入因子與當前容量的乘積時,則要對該雜湊表進行 rehash 操作(即重建內部資料結構),從而雜湊表將具有大約兩倍的桶數。通常,預設載入因子 (0.75) 在時間和空間成本上尋求一種折衷。載入因子過高雖然減少了空間開銷,但同時也增加了查詢成本(在大多數 HashMap 類的操作中,包括 get 和 put 操作,都反映了這一點)。在設定初始容量時應該考慮到對映中所需的條目數及其載入因子,以便最大限度地減少 rehash 操作次數。如果初始容量大於最大條目數除以載入因子,則不會發生 rehash 操作。

  3. 非執行緒安全。

  4. 無序的。

  5. 鍵值不可以重複。如果重複,後邊的值會覆蓋掉早前的值。

  6. Map 介面提供三種collection 檢視,允許以鍵集、值集或鍵-值對映關係集的形式檢視某個對映的內容。

keySet() 返回此對映中包含的鍵的 Set 檢視。

values() 返回此對映中包含的值的 Collection 檢視。

entrySet() 返回此對映中包含的對映關係的 Set 檢視。

八、 HashTable

  1. 和HashMap大體類似,區別:HashTable任何非 null 物件都可以用作鍵或值。還有就是執行緒安全的。

  2. 為了成功地在雜湊表中儲存和獲取物件,用作鍵的物件必須實現 hashCode 方法和 equals 方法。

String、Integer、Double等等這些類都是覆蓋了hashcode()方法的,也就是我們可以不用寫。

equals()相等的兩個物件,hashcode()一定相等; equals()不相等的兩個物件,卻並不能證明他們的hashcode()不相等。換句話說,equals()方法不相等的兩個物件,hashcode()有可能相等。(我的理解是由於雜湊碼在生成的時候產生衝突造成的)。

九、 TreeMap

1. 非執行緒安全

2. 有序,自然順序,自動完成排序。

3. 不可以重複,重複保留後來的。

相關文章