在介紹完Collections框架的各個接口之后,下面我們來看一下各接口都有哪些具體的實現類,以及他們的用途。
實現類按照可以分成如下幾類:
- General-purpose implementations are the most commonly used
implementations, designed for everyday use. They are summarized in the table
below.
- Special-purpose implementations are designed for use in special
situations and display nonstandard performance characteristics, usage
restrictions, or behavior.
- Concurrent implementations are designed to support high concurrency,
typically at the expense of single-threaded performance. These implementations
are part of the
java.util.concurrent
package.
- Wrapper implementations are used in combination with other types of
implementations, often the general-purpose ones, to provide added or restricted
functionality.
- Convenience implementations are mini-implementations, typically made
available via static factory methods, that provide convenient, efficient
alternatives to general-purpose implementations for special collections (for
example, singleton sets).
- Abstract implementations are skeletal implementations that facilitate
the construction of custom implementations — described later in the Custom Collection Implementations section. An advanced topic,
it's not particularly difficult, but relatively few people will need to do it.
我們先來總結一下general-purpose的實現類:
General-purpose
Implementations
Interfaces |
Implementations |
|
Hash table |
Resizable array |
Tree |
Linked list |
Hash table + Linked list |
Set |
HashSet |
|
TreeSet |
|
LinkedHashSet |
List |
|
ArrayList |
|
LinkedList |
|
Queue |
|
|
|
LinkedList |
|
Map |
HashMap |
|
TreeMap |
|
LinkedHashMap |
注意LinkedList同時實現了List和Queue兩種接口。
下表是gegeneral-purpose implementations、special-purpose implementations和concurrent implementations的總結:
Interfaces |
gegeneral-purpose |
special-purpose |
concurrent
|
Set |
HashSet
TreeSet
LinkedHashSet
|
EnumSet
CopyOnWriteArraySet
|
|
List |
ArrayList
LinkedList
|
CopyOnWriteArrayList |
|
Queue |
LinkedList
PriorityQueue
|
|
LinkedBlockingQueue
ArrayBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
|
Map |
HashMap
TreeMap
LinkedHashMap
|
EnumMap
WeakHashMap
IdentityHashMap
|
ConcurrentHashMap |
1. Set實現類
Set有三種general-purpose的實現類,HashSet、TreeSet和LinkedHashSet。其中HashSet速度最快(多數操作都是常數時間),TreeSet(多數操作都是log級時間),但TreeSet有序。LinkedHashSet能提供按照插入順序排列的遍歷,他的速度接近于HashSet,但空間消耗稍大(hash table + linked list)。
HashSet和LinkedHashSet都能在構造函數中指定初始的capacity,和load factor,而TreeSet使不能的。
有一點需要注意的是,HashSet的遍歷時間是與它自身的容量大小(而不是儲存的元素個數)成正比的(線性關系)。因此,如果你要自己指定初始capacity的話,不要搞得太大,那樣不僅浪費空間,而且浪費時間。LinkedHashSet的遍歷時間只與元素個數成正比
Set有兩種special-purpose的實現類:EnumSet和CopyOnWriteArraySet。
·EnumSet的空間和時間性能都很好,可以作為傳統上基于int的“位標志”的替換形式,具有高品質、類型安全的優勢。
·CopyOnWriteArraySet適合于遍歷操作的數量大大超過可變操作的數量時,以及在不能或不想進行同步遍歷,但又需要從并發線程中排除沖突時很有用
具體請參見API doc
2. List實現類
List有兩種General-purpose的實現類:ArrayList和LinkedList。一般情況下,使用ArrayList總是最好的選擇,因為他占用空間小,速度又快。除非你需要大量頻繁的插入刪除操作,這時LinkedList可能更加適合。
ArrayList能在構造函數中指定capacity,LinkedList不能。
List有一種special-purpose的implementation - CopyOnWriteArrayList,具體參考API doc
3. Queue實現類
Queue有兩種general-purpose的實現類:LinkedList和PriorityQueue。LinkedList提供了一種FIFO隊列,而PriorityQueue則是根據元素的自然順序或是指定的Comparator來排列元素。
在java.util.concurrent包里又一個擴展了Queue的BlockingQueue接口。他有如下一些實現類:
4. Map實現類
Map有三種general-purpose的實現類:HashMap、TreeMap和LinkedHashMap。如果你需要SortedMap的操作,或者需要按序遍歷Map,就用TreeMap;如果你不關心遍歷的順序,只關心速度,那就用HashMap;如果你需要接近于HashMap的性能,又想能按元素插入順序來遍歷,就用LinkedHashMap。
其實Map和Set是很相似的,只不過一個是元素集合,一個是“鍵值對”集合。上面介紹的Set中各實現類的性質也同樣適用于Map
需要注意的是,LinkedHashMap提供了一個方法:
removeEldestEntry。通過重寫這個方法,可以定義自覺的策略-
在將新映射關系添加到映射時自動移除舊的映射關系。具體參見API doc
Map有三種Special-purpose的實現類:EnumMap, WeakHashMap,和IdentityHashMap。
Map的Concurrent實現類:ConcurrentHashMap。
下面來介紹一下Wrapper實現類
Wrapper實現類是在提供的Collection實例基礎之上添加一些額外的功能,就好像設計模式中的
decorator
所有的Wrapper都包含在Collections類中,有static方法來創建。
1. Synchronization Wrappers
public static <T> Collection<T>
synchronizedCollection(Collection<T> c);
public static <T> Set<T>
synchronizedSet(Set<T> s);
public static <T> List<T>
synchronizedList(List<T> list);
public static <K,V> Map<K,V>
synchronizedMap(Map<K,V> m);
public static <T> SortedSet<T>
synchronizedSortedSet(SortedSet<T> s);
public static <K,V> SortedMap<K,V>
synchronizedSortedMap(SortedMap<K,V> m);
需要注意的是,不要以為加上Synchronization Wrappers的包裝就可以不管同步操作了,當遍歷的時候,我們還是要對Collection對象加上對象
加上對象鎖。這是因為遍歷操作是由對Collection內部的多個操作的調用組成的。
下面的代碼演示了如何在遍歷時同步:
Collection<Type> c =
Collections.synchronizedCollection(myCollection);
synchronized(c) {
for (Type e : c)
foo(e);
}
注意如果我們是在遍歷Map,不管我們是用key還是用value什么遍歷,都要將鎖加在Map上:
Map<KeyType, ValType> m =
Collections.synchronizedMap(new HashMap<KeyType, ValType>());

Set<KeyType> s = m.keySet();

synchronized(m) { // Synchronizing on m, not s!
while (KeyType k : s)
foo(k);
}
2. Unmodifiable Wrappers
Unmodifiable Wrappers提供如下兩種用途:
2.1. 使Collection不可修改。注意要做到這一點,我們必須在使用Unmodifiable Wrappers后,放棄原來的Collection的引用。
2.2. 運行某客戶端對你的數據進行只讀操作。這時你可以保留原本的Collection的引用,使得你可以隨意操作Collection,而客戶只讀
public static <T> Collection<T>
unmodifiableCollection(Collection<? extends T> c);
public static <T> Set<T>
unmodifiableSet(Set<? extends T> s);
public static <T> List<T>
unmodifiableList(List<? extends T> list);
public static <K,V> Map<K, V>
unmodifiableMap(Map<? extends K, ? extends V> m);
public static <T> SortedSet<T>
unmodifiableSortedSet(SortedSet<? extends T> s);
public static <K,V> SortedMap<K, V>
unmodifiableSortedMap(SortedMap<K, ? extends V> m);
3. Checked Interface Wrappers
Collections類中提供的各種Collections.checked... 操作,返回指定 collection 的一個動態類型安全視圖。試圖插入一個錯誤類型的元素將
導致立即拋出 ClassCastException。假設在生成動態類型安全視圖之前,collection 不包含任何類型不正確的元素,并且所有對該collection
的后續訪問都通過該視圖進行,則可以保證 該 collection 不包含類型不正確的元素。
具體參見API doc
4. Convenience Implementations
4.1 List View of an Array - Arrays.asList()
Arrays.asList()方法返回數組的一個List視圖。任何對返回的list上的操作都將寫回到數組上,反之亦然。但要注意的是,返回的list并不支持
add、remove操作。
Q:如何得到一個固定長度的list?
A:List<String> list = Arrays.asList(new String[size]);
4.2 Immutable Multiple-Copy List
參見Collections.nCopies()方法
4.3 Immutable Singleton Set
參見Collections.singleton()方法
4.4 Empty Set, List, and Map Constants
Collections.emptySet(), Collections.emptyList(), Collections.emptyMap()