1. 程式人生 > >LinkedList、ArrayList、Vector、Stack的實現原理和差異

LinkedList、ArrayList、Vector、Stack的實現原理和差異

相互關係

  • LinkedList、ArrayList、Vector 都繼承自 AbstractList;都實現了 List 介面,主要包括 size(), isEmpty(), contains(Object), iterator(), toArray(), add(E), remove(), get(int), sort(), clear(), set(int, E), subList(int, int), listIterator() 等方法。
  • LinkedList 實現了 Deque 介面(主要是對首尾元素的新增刪除方法), Vector 和 ArrayList 實現了 RandomAccess 介面。
  • 它們都是泛型類,可以存放任意型別的物件。
public class LinkedList<E> extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io
.Serializable public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable public class Stack<E> extends Vector<E>
  • 類的繼承關係
AbstractCollection
    -> AbstractList
        -> AbstractSequentialList - > LinkedList
-> ArrayList -> Vector -> Stack

實現原理和執行緒安全性

LinkedList

  • LinkedList 可以看做為一個雙向連結串列,所有的操作都可以認為是一個雙向連結串列的操作,實現了 List 和 Deque 介面。LinkList 可以很方便地在連結串列頭或者連結串列尾插入資料,或者在指定結點前後插入資料,還提供了取走連結串列頭或連結串列尾的結點,或取走中間某個結點的方法。
  • LinkedList 沒有同步方法,是執行緒不安全的。
  • 如果多個執行緒同時訪問一個List,必須自己實現訪問同步。一種解決方法是在建立List時構造一個同步的List list = Collections.synchronizedList(new LinkedList(…));
  • 成員變數: 
transient int size = 0;
transient Node<E> first; // 使用結點<Node>來存放資料的, first指向連結串列頭
transient Node<E> last; // last指向連結串列尾
  • Node 資料結構
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
        // more code
    }

ArrayList

  • ArrayList實現了可變大小的陣列。它允許所有元素,包括null。
  • ArrayList沒有同步,是執行緒不安全的。
  • 成員變數:
transient Object[] elementData; // 存放物件的陣列,第一次插入資料時初始化為DEFAULT_CAPACITY=10大小
private int size; // 陣列大小
  • 擴容:
    • ArrayList 的容量 capacity 可隨著不斷新增新元素而自動增加,正常情況下每次增加當前陣列大小的一半。
    • 擴容時拷貝舊資料生成一個 newCapacity 大小的新陣列,然後將elementData指向新陣列。
    • 擴容時機:
      • add元素前,先確保 catacity>=size+1。
      • 當需要插入大量元素時,在插入前可以呼叫 ensureCapacity(int minCapacity) 方法來增加ArrayList的容量以提高插入效率, 引數 minCapacity 為希望調整到的最小容量。

Vector

  • Vector也是一個類似於ArrayList的可變長度的陣列型別,它的內部也是使用陣列來存放資料物件的。
  • Vector與ArrayList唯一的區別是,Vector是執行緒安全的,即它的大部分方法都包含有關鍵字synchronized,因此,若對於單一執行緒的應用來說,最好使用ArrayList代替Vector,因為這樣效率會快很多(類似的情況有StringBuffer與StringBuilder);而在多執行緒程式中,為了保證資料的同步和一致性,可以使用Vector代替ArrayList實現同樣的功能。
  • 成員變數:
protected Object[] elementData;
protected int elementCount;
protected int capacityIncrement; // 每次容量增長值,如果<=0,則每次增長當前陣列大小。

Stack

  • Stack繼承自Vector,實現一個後進先出的堆疊。Stack提供5個額外的方法使得 Vector得以被當作堆疊使用。基本的push和pop方法,還有peek方法得到棧頂的元素,empty方法測試堆疊是否為空,search方法檢測一個元素在堆疊中的位置。Stack剛建立後是空棧。

總結

List 實現原理 執行緒安全性 備註
LinkedList 雙向連結串列 不安全 相對於ArrayList,插入或增加效率高,查詢效率低;使用資料頻繁出入的情況。
ArrayList 陣列 不安全 試用與陣列變動不大,主要用來查詢的情況。
Vector 陣列 安全
Stake 陣列 安全 繼承自Vector,新增額外方法實現後進先出的堆疊