Java中Vector ArrayList LinkedList之間的區別與聯繫
ArrayList :
List 接口的大小可變數組的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 List 接口外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。(此類大致上等同於 Vector 類,除了此類是不同步的 。)
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時間運行。add 操作以分攤的固定時間 運行,也就是說,添加 n 個元素需要 O(n) 時間。其他所有操作都以線性時間運行(大體上講)。與用於 LinkedList 實現的常數因子相比,此實現的常數因子較低。
每個 ArrayList 實例都有一個容量。該容量是指用來存儲列表元素的數組的大小。它總是至少等於列表的大小。隨着向 ArrayList 中不斷添加元素,其容量也自動增長。並未指定增長策略的細節,因爲這不只是添加元素會帶來分攤固定時間開銷那樣簡單。
在添加大量元素前,應用程序可以使用 ensureCapacity 操作來增加 ArrayList 實例的容量。這可以減少遞增式再分配的數量。
Vector :
Vector 類可以實現可增長的對象數組。與數組一樣,它包含可以使用整數索引進行訪問的組件。但是,Vector 的大小可以根據需要增大或縮小,以適應創建 Vector 後進行添加或移除項的操作。
每個向量會試圖通過維護 capacity 和 capacityIncrement 來優化存儲管理。capacity 始終至少應與向量的大小相等;這個值通常比後者大些,因爲隨着將組件添加到向量中,其存儲將按 capacityIncrement 的大小增加存儲塊。應用程序可以在插入大量組件前增加向量的容量;這樣就減少了增加的重分配的量。
LinkedList :
List 接口的鏈接列表實現。實現所有可選的列表操作,並且允許所有元素(包括 null)。除了實現 List 接口外,LinkedList 類還爲在列表的開頭及結尾 get、remove 和 insert 元素提供了統一的命名方法。這些操作允許將鏈接列表用作堆棧、隊列或雙端隊列。
此類實現 Deque 接口,爲 add、poll 提供先進先出隊列操作,以及其他堆棧和雙端隊列操作。
所有操作都是按照雙重鏈接列表的需要執行的。在列表中編索引的操作將從開頭或結尾遍歷列表(從靠近指定索引的一端)。
注意,此實現不是同步的。如果多個線程同時訪問一個鏈接列表,而其中至少一個線程從結構上修改了該列表,則它必須 保持外部同步。
ArrayList 與 Vector:
ArrayList 與 Vector 基本相同,不同的是Vector是同步的,而ArrayList不是同步的,所以ArrayList速度會比較快。
ArrayList 與 LinkedList:
ArrayList 是通過數組實現的,所以隨機訪問的速度是O(1),而從其中插入、刪除元素的話會複製數組,開銷較大。
LinkedList 是通過鏈表實現的,所以插入、刪除元素會很快,但是隨機訪問的速度就較慢了。可以當作堆棧、隊列或雙端隊列使用。
ArrayList的刪除元素的方法:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
ArrayList獲取指定下標的元素的方法:
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
LinkedList的刪除元素的方法:
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
LinkedList獲取指定下標的方法:
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}