一、Collection是什麼
首先我們一起來探討一下Collection究竟是什麼個玩意,如上圖所示List、Set、Queue、Map都指向Collection,它們都只是一個介面,並不是實現類。正因為有了Collection集合框架,使我們能方便的批量運算元據或物件。
二、List
List是有序的Collection,我們可以非常輕鬆的來控制資料插入的位置,並且也能根據其索引來訪問List中的某個元素。
其實List實現類還是挺多的【AbstractList, AbstractSequentialList, ArrayList, CopyOnWriteArrayList, LinkedList, Stack, Vector】,但今天我們主要來講講常用的類ArrayList、LinkedList、Vector。
2.1 ArrayList
看名稱就知道Arraylist是基於陣列的連結串列,且執行緒不同步。我們可以看下其實現的add方法原始碼:
@Override
public boolean add(E object) {
Object[] a = array;
int s = size;
if (s == a.length) {
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : s >> 1)];
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
a[s] = object;
size = s + 1;
modCount++;
return true;
}
複製程式碼
2.2 Vector
Vector也是基於陣列的連結串列,但是其執行緒是同步的【如下add方法被synchronized修飾】,其實現的add方法原始碼:
@Override
public synchronized boolean add(E object) {
if (elementCount == elementData.length) {
growByOne();
}
elementData[elementCount++] = object;
modCount++;
return true;
}
複製程式碼
效能方面:Vector比Arraylist和Array都低;
執行緒方面:Vector執行緒同步,ArrayList執行緒不同步;
2.3 LinkedList
LinkedList與Vector、ArrayList有著明顯的區別,其並不基於陣列,所以對LinkedList元素進行增加、刪除時,不需要批量移動其他元素。
其每個節點都包含以下兩個資訊:
1、該節點的資料
2、下一個節點的資訊
小總結:基於Array的List(Vector、ArrayList)適合查詢,LinkedList適合增刪操作。
三、Set
Set是不包含重複的元素的無序Collection,並且Set都是基於Map實現的。
如果使用add()方法存入已存在的元素,則會覆蓋之前的元素。
基於Set實現的類有AbstractSet, CopyOnWriteArraySet, EnumSet, HashSet, LinkedHashSet, TreeSet。
3.1 HashSet
我們可以先看下HashSet中的add()方法的原始碼:
transient HashMap<E, HashSet<E>> backingMap;
@Override
public boolean add(E object) {
return backingMap.put(object, this) == null;
}
複製程式碼
其中backingMap為HashMap物件,我們應該知道HashMap是以鍵值對的形式來儲存資料的,而在上述add()方法中,鍵為傳入的物件,所以這就是Set不包含重複元素的最根本原因。
3.2 TreeSet
TreeSet是SortedSet的子類,它與HashSet最根本的區別在於:TreeSet是有序的,因為TreeSet是基於SortedMap來實現的。
四、Map
我們在聊Set的時候說道了HashMap,所以Map始終是以鍵值對形式存在的,並且其中的鍵是不允許重複的。
Map的常見實現有:HashMap和TreeMap。
如果我們要往HashMap中存入資料就可以使用put(Object key,Object value)方法,如果要取出資料也特別簡單,使用get(Object key)方法。
在這裡,我主要想聊聊HashMap和HashTable兩個類的區別:
一、HashTable類是基於抽象類Dictionary的,而HashMap類是基於Map介面的實現;
二、HashTable類是同步的,這就保證了執行緒的安全,HashMap類是不同步的;
三、HashTable類元素不能為空,否則系統會拋空指標異常,而HashMap類value是可以為空的,當然啦,其中key也是可以為空的,但是如果我們這樣設定,似乎毫無意義。
複製程式碼
五、Queue
Queue(佇列)先進先出,Stack(棧)後進先出。
方法名 方法含義 備註
add 增加一個元索 如果佇列已滿,則丟擲一個IIIegaISlabEepeplian異常
remove 移除並返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
element 返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
offer 新增一個元素並返回true 如果佇列已滿,則返回false
poll 移除並返問佇列頭部的元素 如果佇列為空,則返回null
peek 返回佇列頭部的元素 如果佇列為空,則返回null
put 新增一個元素 如果佇列滿,則阻塞
take 移除並返回佇列頭部的元素 如果佇列為空,則阻塞