Java容器型別使用總結

四火的嘮叨發表於2015-02-15

最近抽空把java.lang下面常用的那些容器型別(資料結構)複習了一下,這些東西是基礎,平時使用的時候也可以很容易查得到,有些方法大概知道,但是總是弄混,如果可以記住那些重要方法,並且能夠熟練使用的話,還是可以讓編碼過程變得容易很多。另外一個是實現機制,對於常用資料結構的實現機制,應該說是必須要熟知的。

另外,併發容器我之前整理過,放在這篇文章裡。

Queue

  1. add和offer的區別在於達到上限時add丟擲異常,offer返回false;
  2. remove和poll的區別在於,佇列為空時前者丟擲異常,後者返回空;
  3. element和peek都返回佇列頭部元素,但是前者失敗不丟擲異常,後者返回空。
boolean add(E e);
boolean offer(E e);

E remove();
E poll();

E element();
E peek();

PriorityQueue,內部實現是一個Object[] queue承載的堆。

Deque,雙端佇列(double-ended queue),在Queue基礎上,增加了這樣幾個方法:

void addFirst(E e);
void addLast(E e);

boolean offerFirst(E e);
boolean offerLast(E e);

E removeFirst();
E removeLast();

E pollFirst();
E pollLast();

E getFirst();
E getLast();

E peekFirst();
E peekLast();

boolean removeFirstOccurrence(Object o);
boolean removeLastOccurrence(Object o);

ArrayDequeue:陣列實現,擴容策略是容量翻倍。

List

boolean add(E e);
boolean remove(Object o);
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);

ArrayList,擴容策略是(oldCapacity * 3)/2 + 1。

LinkedList,它除了實現自List介面外,還實現了Deque介面。

Vector,實現自List介面,內部實現是個陣列,執行緒安全,擴容策略是(capacityIncrement > 0) ? (oldCapacity + capacityIncrement) : (oldCapacity * 2)。

Stack是Vector的子類,增加了一些棧的方法:

E push(E item)
E pop()
E peek()
boolean empty()

Map

boolean containsKey(Object key);
boolean containsValue(Object value);

V get(Object key);
V put(K key, V value);
V remove(Object key);

Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();

SotedMap介面,key是有序的map:

SortedMap<K, V> subMap(K paramK1, K paramK2);
SortedMap<K, V> headMap(K paramK);
SortedMap<K, V> tailMap(K paramK);

K firstKey();
K lastKey();

子介面NavigableMap,提供了一些根據某個key尋找它前面或者後面的key的方法。其中floorKey/celingKey表示的關係是小於等於/大於等於,lower/higher表示的關係是嚴格的小於/大於:

Map.Entry<K,V> floorEntry(K key)
K floorKey(K key)
Map.Entry<K,V> ceilingEntry(K key)
K ceilingKey(K key)

Map.Entry<K,V> lowerEntry(K key)
K lowerKey(K key)
Map.Entry<K,V> higherEntry(K key)
K higherKey(K key)

TreeMap是NavigableMap的直接實現子類,內部實現是一個紅黑樹。

EnumMap,結構是<K extends Enum<K>, V>,內部是通過一個K[] keyUniverse和一個Object[] vals來實現的。

HashMap,內部是陣列+連結串列實現的,達到threshold = capacity * loadFactor時,擴容策略為:numKeysToBeAdded / loadFactor + 1。

HashTable,實現自Dictionary和Map,方法都是執行緒安全的。HashTable的put方法,value不可以為空,這是它和HashMap的一個不同;再有二者找桶的hash方法不同;最後則是threshold計算邏輯相同,但它的擴容策略不同:oldCapacity * 2 + 1。HashTable、HashMap和HashSet經常被放到一起比較。

Properties,是HashTable的子類,方法執行緒安全。

IdentityHashMap,比較key不是使用equals來比較,而是使用“==”來比較,只要地址不等(即不是同一個物件)即可共存,也就是說,key是可以重複的。

LinkedHashMap,在HashMap的基礎上,又單獨維護了一個雙向迴圈連結串列。有一個重要引數是accessOrder,accessOrder為true時,每次呼叫get方法訪問行為發生後,會把最近訪問的物件移動到頭部,而超出容量移除物件時,是從尾部開始的,利用它並且覆寫boolean removeEldestEntry方法可以實現一個LRU的佇列。

WeakHashMap,但是key是weak引用,在不被使用時自動清除,擴容策略:tab.length * 2。原理上看:Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V>,因此entry是弱引用的實現類,關鍵方法是expungeStaleEntries,它在對這個map各種操作的時候都會被呼叫到,而這個方法裡面也是靠監聽key的ReferenceQueue這個佇列的狀態來確定是否真的沒有物件引用了。

Set

boolean contains(Object o);
boolean add(E e);
boolean remove(Object o);

SortedSet,介面方法和SortedMap類似:

SortedSet<E> subSet(E fromElement, E toElement);
SortedSet<E> headSet(E toElement);
SortedSet<E> tailSet(E fromElement);

E first();
E last();

相應地,NavigableSet和NavigableMap類似,方法就不列出了。

TreeSet則和TreeMap類似,其實內部實現就是一個TreeMap。

HashSet,尤其注意的是,有兩種實現,當構造方法引數小於3個時,內部使用HashMap,否則,使用LinkedHashMap。

RegularEnumSetJumboEnumSet,前者是普通的列舉set(用位移來表示各種組合的可能,達到空間佔用最小,最大不能超過64個列舉值),後者適合數量較大的列舉set(老老實實地使用物件陣列)。

LinkedHashSet,其實和LinkedHashMap是一個東西。

BitSet,叫set但是沒有實現set的介面。用位元位來存放某個數是否存在,比如僅僅一個long,64位,就可以存放0~63的數,內部實際的資料型別是long[]。

void flip(int bitIndex);
void flip(int fromIndex, int toIndex);

void set(int bitIndex);
void set(int fromIndex, int toIndex, boolean value);

void clear(int bitIndex);

int length();
int size();

其中size方法返回實際使用了的位元位數目;length方法返回邏輯意義上的長度(比如表示的數裡面最大是80,那麼加上0,它的邏輯意義上的長度就是81)。

擴容策略:Math.max(2 * words.length, wordsRequired)。

Dictionary

Enumeration<K> keys();
Enumeration<V> elements();

V get(Object key);
V put(K key, V value);
V remove(Object key);

已經被廢棄了,用Map來實現相同功能。

最後這張圖來自這個網站,對於從巨集觀上把握這些容器型別實在是太有幫助了:

Java容器型別複習筆記

相關文章