Java集合從菜鳥到大神演變

茅坤寶駿氹發表於2018-05-02

轉載自 Java集合從菜鳥到大神演變

先來看一張集合概況圖,這裡從上到下列舉了幾個最經常用的集合

1、集合介面

java.util.Collection 是一個集合介面。它提供了對集合物件進行基本操作的通用介面方法。Collection介面在Java 類庫中有很多具體的實現。Collection介面的意義是為各種具體的集合提供了最大化的統一操作方式。宣告瞭適用於JAVA集合(只包括Set和List)的通用方法。Set 和List 都繼承了Conllection,Map沒有.


2、集合型別

JAVA集合主要分為三種型別:Set(集),List(列表),Map(對映)


Set集合:集合元素是不能重複的,元素是沒有順序的,所以它不能基於位置訪問元素。


List集合: 集合元素是可以重複的,元素是有順序的,所以它可以基於位置訪問元素。


Map:它包含鍵值對。Map的鍵是不能重複的,可以保證元素的插入順序,也可以排序。


3、集合介紹

Set(集):

HashSet

HashSet是基於HashMap實現的,它不允許出現重複元素,不保證和政集合中元素的順序,允許包含值為null的元素,但最多隻能有一個null元素。


TreeSet

TreeSet可以實現排序等功能的集合,它在講物件元素新增到集合中時會自動按照某種比較規則將其插入到有序的物件序列中,並保證該集合元素按照“升序”排列。

  

LinkedHashSet

具有HashSet的查詢速度,且內部使用連結串列維護元素的順序(插入的次序),於是在使用迭代器遍歷Set時,結果會按元素插入的次序顯示。


List(列表):

ArrayList

內部結構基於陣列實現,可以對元素進行隨機的訪問,向ArrayList中插入與刪除元素的速度慢。


LinkedList

LinkedList 是一個繼承於AbstractSequentialList的雙向連結串列,可以被當作堆疊、佇列或雙端佇列進行操作。LinkedList同時還實現了List、Deque(雙端佇列)、Cloneable(能克隆)、java.io.Serializable(支援序列化,能通過序列化去傳輸)等介面,LinkedList是非同步的。

每個節點除含有元素外,還包含向前,向後的指標。 
新建一個LinkedList,生成一個頭節點(header,就是一個頭指標),它的元素為null。 

它自包含,next和previous指標都指向自己。 執行add(Object obj)方法後,會生成一個新節點 
 


Header節點的next指向連結串列的第一個節點,previous指向連結串列的最後一個節點,在這裡都是first,再增加一個物件,它的形狀像下面這樣。 


Vector

Vector 是向量佇列,它是JDK1.0版本新增的類。繼承於AbstractList,實現了List(支援相關的新增、刪除、修改、遍歷等), RandomAccess(隨機訪問功能), Cloneable(能被克隆)這些介面。


Vector實際上是通過一個陣列去儲存資料的。當我們構造Vecotr時;若使用預設建構函式,則Vector的預設容量大小是10。


當Vector容量不足以容納全部元素時,Vector的容量會增加。若容量增加係數 >0,則將容量的值增加“容量增加係數”;否則,將容量大小增加一倍。Vector的克隆函式,即是將全部元素克隆到一個陣列中。和ArrayList不同,Vector中的操作是執行緒安全的。


Stack

Stack是棧,它的特性是:先進後出(FILO, First In Last Out)。

Stack繼承於Vector(向量佇列)的,由於Vector是通過陣列實現的,這就意味著,Stack也是通過陣列實現的,而非連結串列。


Map(對映):

  Map基於雜湊表的實現,Map 是一種把鍵物件和值物件對映的集合,它的每一個元素都包含一對鍵物件和值物件。

HashMap

HashMap底層就是一個陣列結構(叫做Entry Table),陣列中的每一項又是一個連結串列(叫做Bucket,用於解決hash衝突而設計的)。當新建一個HashMap的時候,就會初始化一個陣列。插入和查詢“鍵值對”的開銷是固定的,可以通過構造器設定容量capacity和負載因子load factor,以調整容器的效能。初始化結構如下:

  

每個bucket包含一個Entry(map自定義的一種結構,包含一個往後的指標)的連結串列。 
在put(key, value)後,它的結構如下:


LinkedHashMap

類似於HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序,只比HashMap慢一點。而在迭代訪問時發而更快,因為它使用連結串列維護內部次序。

  

TreeMap

基於紅黑樹資料結構的實現,檢視“鍵”或“鍵值對”時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點在於,你得到的結果是經過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。

  

WeakHashMap

弱鍵(weak key)Map,Map中使用的物件也被允許釋放: 這是為解決特殊問題設計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。

  

IdentifyHashMap

使用==代替equals()對“鍵”作比較的hash map,專為解決特殊問題而設計。


Hashtable

Hashtable與HashMap類似,Hashtable繼承自Dictionary類,實現了Map介面,不同的是它不允許記錄的鍵或者值為空;和HashMap相比,Hashtable是執行緒同步的,即任一時刻只有一個執行緒能寫Hashtable,因此也導致了 Hashtable在寫入時會比較慢。而且Hashtable可以通過Enumeration去遍歷。

 

        

4、總結

List按物件進入的順序儲存物件,不做排序或編輯操作。

Set對每個物件只接受一次,並使用自己內部的排序方法(通常,你只關心某個元素是否屬於Set,而不關心它的順序--否則應該使用List)。

Map同樣對每個元素儲存一份,但這是基於"鍵"的,Map也有內建的排序,因而不關心元素新增的順序。

如果新增元素的順序對你很重要,應該使用 LinkedHashSet/TreeSet或者LinkedHashMap/TreeMap. 


最後還要提到集合類裡面一個很重要的類:Collections,它有很多自己獨特的靜態方法。當然它主要提供幾種特殊集合(List, Map,Set),可以呼叫靜態方法來獲得:Unmodifiable*(不可修改集合,不可新增或刪除元素),Synchronize*(保持同步集合,它的基本每個方法都加鎖,防止併發操作),Checked*(宣告之始傳入特定型別,以後的操作都會驗證加入元素是否屬於已定型別),Singleton*(集合中只包含一個元素)。它們都是通過包裝集合類中的抽象類獲得,產生不同的行為。 


相關文章