Java 集合架構

來源:互聯網
上載者:User

-- Start

ListArrayList

ArrayList 是一個可變數組, 它有數組的所有優缺點, 如高效的隨機訪問, 低效的插入和刪除. 它允許重複值, 允許null, 有序(所謂的有序指的是讀取元素的順序和插入的順序一致).

Vector

Vector 除了提供了同步外, 它和 ArrayList 沒有任何區別, 因為它是安全執行緒的, 所以效率比較差, Java 推薦我們盡量使用 ArrayList.

Stack

Stack 是一種後進先出的資料結構, 它繼承自Vector, 所以它也是安全執行緒的. 由於設計上的缺陷, 現在已經不推薦使用了, 推薦使用 Deque.

CopyOnWriteArrayList

CopyOnWriteArrayList 是一個安全執行緒的 ArrayList, 當我們構建一個迭代器時, 它對當前數組的引用, 如果數組被修改了, 它仍然引用舊的數組. 這種設計對讀線程大大多於寫線程時, 非常有用.

LinkedList

LinkedList 是一個雙向列表, 它的特點是高效插入和刪除, 低效的隨機訪問, 所以千萬不要使用像 get(int index) 等包含索引資訊的方法. 問題是有時候我們並不知道某個List 到底是Arraylist 還是LinkedList, 為此, JDK 1.4 引入了一個介面 RandomAccess,它沒有任何方法,只是用來標記某個list 是否支援高效的隨機訪問。 所以,我們可以使用下面的代碼來判讀某個list是否支援高效的隨機訪問。

if (list instanceof RandomAccess) {...} else {...}

 除此之外, 它允許重複值, 允許null, 有序.

Set

HashSet

HashSet 不允許有重複值, 允許有一個null, 它的優點是可以快速的幫我們尋找對象, 缺點是我們無法控制對象的順序.

LinkedHashSet

LinkedHashSet 繼承了 HashSet, 它克服了 HashSet 的缺點, 我們可以按照對象插入的順序來迭代對象.

TreeSet

TreeSet 不允許有重複值, 允許有一個null, 它包含的對象是經過排序的, 排序之後形成一個樹狀結構, 這就是叫它 TreeSet 的原因. 因為它要排序, 所以加入它的對象必須實現 Comparable 介面或在建立 TreeSet 時提供比較子(Comparator), 在迭代 TreeSet 時, 我們可以按照升序迭代, 也可以按照降序迭代.

ConcurrentSkipListSet

Skip List 是一種資料結構, 它在有序鏈表的基礎上進行了擴充, 解決了有序鏈表尋找特定值困難的問題。 因為鏈表不能像數組那樣進行二分尋找, 所以在最壞的情況下, 我們需要遍曆整個列表才能找到我們需要的值. 但是如果每個節點儲存了它後面2個節點地址的話, 遍曆時我們就可以跳過中間的節點, 如: 從第1個節點直接跳到第3個節點, 在最壞的情況下, 需要遍曆 n/2+1 個節點. 如果每個節點儲存了它後面4個節點地址的話, 我們就可以從第1個節點直接跳到第5個節點, 在最壞的情況下, 我們需要遍曆 n/4+1
個節點, 這就是跳錶(Skip List)的思想, 這是一種以空間換取時間的思想.

ConcurrentSkipListSet 不允許有重複值, 不允許有null, 它包含的對象是經過排序的, 使用 Skip List 資料結構儲存. 因為它要排序, 所以加入它的對象必須實現 Comparable 介面或在建立 ConcurrentSkipListSet 時提供比較子(Comparator). 除此之外, 它還是安全執行緒的, 我們可以按照升序迭代, 也可以按照降序迭代, 不過如果隨後某個值被修改了, 迭代時仍然引用舊的值.

CopyOnWriteArraySet

CopyOnWriteArraySet 是一個安全執行緒的 Set, 它內部使用的是 CopyOnWriteArrayList, 所以它們都有共同的特點, 當我們構建一個迭代器時, 它對當前數組的引用, 如果數組被修改了, 它仍然引用舊的數組. 這種設計對讀線程大大多於寫線程時, 非常有用.

EnumSet

EnumSet 只能包含某種枚舉類型的對象, 不允許有重複值, 不允許有null. 迭代順序和它們在枚舉中定義的順序一致.

Map

HashMap

HashMap 允許null值和null鍵. 它的優點是可以快速的幫我們尋找對象, 缺點是我們無法控制對象的順序.

LinkedHashMap

LinkedHashMap 繼承自 HashMap. 它克服了 HashMap 的缺點, 我們可以按照對象插入順序訪問順序來迭代對象, 這取決於你使用的構造方法. 當我們使用下面的構造方法構造一個LinkedHashMap後, 每當訪問其中的元素時, 該元素就會從當前的位置移到鏈表的尾部, 由此我們可以知道, 離鏈表開頭越近的元素使用的最少, 這就是傳說中的“最少最近原則”, 這個特性對於實現快取非常有用, 例如, 我們可能希望將最常訪問的元素放到緩衝中,
而將不長訪問的元素放到資料庫中.

LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
Hashtable

Hashtable 和 HashMap 的主要區別在於 Hashtable 是線程同步的, 除此之外, Hashtable 不允許有 Null 值和 Null 鍵.

ConcurrentHashMap

ConcurrentHashMap 是安全執行緒的, 它使用了非常複雜的演算法, 永遠也不會鎖住整個表, 而是只鎖定表的某個片段, 從而提高了並發性. 它的迭代器只能反映構建時的狀態, 如果建立迭代器之後資料修改了, 迭代器還是引用舊的資料. 除此之外, 它不允許有 Null 值和 Null 鍵.

WeakHashMap

如果 Map 中的鍵對象沒有實現 equals 方法(也就是說 equals 方法的行為和 == 是一致的), 那麼如果在 Map 外部沒有這個鍵對象, 我們將不能尋找 Map 中的這個元素了, 但是記憶體回收行程並不會回收這個元素. WeakHashMap 就是為瞭解決這個問題而設計的, 在這種情況下, WeakHashMap 中的這個元素將被記憶體回收行程回收. 除此之外, 它和 HashMap 沒有任何區別.

IdentityHashMap

在 HashMap 中, 它用 equals 方法來判斷兩個鍵是否相等, 而在 IdentityHashMap 中, 它用 == 來判斷兩個鍵是否相等. 除此之外, 它和 HashMap 沒有任何區別.

TreeMap

TreeMap 的鍵是經過排序的, 排序之後形成一個樹狀結構, 這就是叫它 TreeMap 的原因. 因為它要排序, 所以加入它的鍵必須實現 Comparable 介面或在建立 TreeMap 時提供比較子(Comparator). 除此之外, 它還提供了一些按鍵檢索的方法.

ConcurrentSkipListMap

Skip List 是一種資料結構, 它在有序鏈表的基礎上進行了擴充, 解決了有序鏈表尋找特定值困難的問題。 因為鏈表不能像數組那樣進行二分尋找, 所以在最壞的情況下, 我們需要遍曆整個列表才能找到我們需要的值. 但是如果每個節點儲存了它後面2個節點地址的話, 遍曆時我們就可以跳過中間的節點, 如: 從第1個節點直接跳到第3個節點, 在最壞的情況下, 需要遍曆 n/2+1 個節點. 如果每個節點儲存了它後面4個節點地址的話, 我們就可以從第1個節點直接跳到第5個節點, 在最壞的情況下, 我們需要遍曆 n/4+1
個節點, 這就是跳錶(Skip List)的思想, 這是一種以空間換取時間的思想.

ConcurrentSkipListMap 是安全執行緒的, 不允許有 null 鍵和 null 值, 它的鍵是經過排序的, 使用 Skip List 資料結構儲存, 所以加入它的鍵必須實現 Comparable 介面或在建立 ConcurrentSkipListMap 時提供比較子(Comparator), 除此之外, 它也提供了一些按鍵檢索的方法.

EnumMap

EnumMap 不允許null鍵, 允許null值. 它的鍵必須是某個枚舉類型.

隊列(Queue)

隊列(Queue)是一種先進先出的資料結構, 但是 Java 中 Queue 的有些實作類別並不是先進先出的, 如: PriorityQueue, PriorityBlockingQueue. Queue 不允許有 null 值, 因為 poll 方法返回 null 來指示 Queue 中沒有元素了.

PriorityQueue

優先順序隊列(PriorityQueue)中的元素是經過排序的, 所以加入它中的元素必須實現了 Comparable 介面或構建優先順序隊列時指定比較子. 我們可以按照任意的順序加入元素, 但是 poll, remove, peek 等方法返回的總是最小的那個元素. 需要注意的是當我們迭代優先順序隊列時, 迭代的順序是不確定的. 其次, 它沒有容量限制, 不允許有null, 它是非安全執行緒的. 使用優先順序隊列的一個典型的例子是任務調度, 每個任務都有一個優先順序, 任務以任何的順序加入優先順序隊列, 優先順序高的總是被第一個取出.

ConcurrentLinkedQueue

ConcurrentLinkedQueue 是一種先進先出的資料結構, 它安全執行緒的, 沒有容量限制, 它不允許 null 值. 它的迭代器只能反映構建時的狀態, 如果建立迭代器之後資料修改了, 迭代器還是引用舊的資料

阻塞隊列(BlockingQueue)

Java 1.5 加入了阻塞隊列(BlockingQueue), 它大大簡化了我們編寫經典的生產者-消費者線程的工作量, 我們再也不需要使用 wait, notifyAll 等方法來同步生產者和消費者線程. 生產者線程只管往 BlockingQueue 中加入資料, 如果 BlockingQueue 的容量已滿, 則 put 方法阻塞直到有容量為止. 消費者線程只管從 BlockingQueue 中讀取資料, 如果 BlockingQueue 中沒有資料, 則 take 方法阻塞直到有資料為止. 很明顯,
生產者線程需要在所有的資料都加入 BlockingQueue 後, 加入一個特殊的資料(如:EOF), 以此來告訴消費者線程資料已讀完, 否則消費者線程會一直等待不會結束.

ArrayBlockingQueue

ArrayBlockingQueue 是底層使用數組儲存資料的阻塞隊列.

LinkedBlockingQueue

LinkedBlockingQueue 是底層使用鏈表資料結構儲存資料的阻塞隊列.

PriorityBlockingQueue

PriorityBlockingQueue 是一種阻塞隊列, 除了提供了安全執行緒和阻塞外, PriorityBlockingQueue 和 PriorityQueue 非常類似.

DelayQueue

DelayQueue 是一種特殊的阻塞隊列, 加入它中的元素必須實現 Delayed 介面, 只有到期的元素才能被取出, 最先取出的元素是到期時間最長的元素.

SynchronousQueue

SynchronousQueue 是一種特殊的阻塞隊列, 它不能容納任何元素, 它的插入操作會被阻塞直到另一個線程讀取, 反之亦然. 它被用來在多個線程之間同步傳遞資料.

LinkedTransferQueue

LinkedTransferQueue 是一種特殊的阻塞隊列, 它既可以當做 LinkedBlockingQueue 來使用, 也可以當做 SynchronousQueue 來使用. 所以, 它可以用來在多個線程之間同步傳遞資料, 以用來非同步傳遞資料.

雙端隊列(Deque)

雙端隊列(Deque) 也是一種 queue, 它是 "double ended queue" 的縮寫, 讀作 "deck". 顧名思義, 我們可以在 Deque 的兩端進行插入和刪除操作. 它既可以用作先進先出的隊列, 也可用作後進先出的棧.

ArrayDeque

ArrayDeque 是一種底層採用數組儲存的 Deque.

LinkedList

LinkedList 是一種底層採用鏈表格儲存體的 Deque.

ConcurrentLinkedDeque

除了安全執行緒外, 它和 LinkedList 很相似.

LinkedBlockingDeque

LinkedBlockingDeque 是一種底層採用鏈表格儲存體的阻塞雙端隊列.

Arrays 和 Collections

這兩個類是工具類, 它們包含了很多非常實用的靜態方法, 如下面的兩個方法可以協助我們實現數組與列表的相互轉換。

Arrays.asListList.toArray

 

如果我們的集合需要在多線程環境下使用, 我們可以使用下面的方法來封裝集合。

Collections.synchronizedCollectionCollections.synchronizedListCollections.synchronizedMapCollections.synchronizedSetCollections.synchronizedSortedMapCollections.synchronizedSortedSet

如果我們想建立唯讀集合,那麼我們可以使用面的方法來封裝集合。

Collections.unmodifiableCollectionCollections.unmodifiableListCollections.unmodifiableMapCollections.unmodifiableSetCollections.unmodifiableSortedMapCollections.unmodifiableSortedSet

如果你想對列表進行排序,你可以使用下面的方法。

Collections.sortCollections.reverseOrderCollections.shuffle

總之,這兩個類提供許多非常有用的方法。

 

---更多參見:Java 精萃
-- 聲 明:轉載請註明出處
-- Last Updated on 2012-10-24
-- Written by ShangBo on 2012-09-19
-- End

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.