API 地址:http://docs.oracle.com/javase/6/docs/api/
涉及概念之間的關係如下:
圖解:
List 是一個接口,它繼承於Collection的接口。它代表着有序的隊列。它允許重複的元素。
AbstractList 是一個抽象類,它繼承於AbstractCollection。AbstractList實現List接口中除size()、get(int location)之外的函數。
AbstractSequentialList 是一個抽象類,它繼承於AbstractList。它的方法較少。專門爲LinkedList而設計。
ArrayList, LinkedList, Vector, Stack是List的4個實現類。
ArrayList 通過一個Object[]數組存儲對象,要注意這個數組是transient類型的。它的add()和remove()方法是通過System.arraycopy(...)實現的,get()方法就是返回數組的一個元素。
AbstractSequentialList 進一步地實現了add()、get()以及remove()方法。它通過調用ListIterator類中相應的方法實現這些方法。這樣的目的是通過雙向列表的特性,提高執行速度。它把listIterator(int index)方法聲明爲abstract類型,要求用戶必須重新實現。在添加和刪除元素時具有比ArrayList更好的性能.但在get與set方面弱於ArrayList。
LinkedList 繼承自AbstractSequentialList,通過一個雙向鏈表存儲對象。注意這個鏈表的header是transient類型的。這裏的header中是不包含實際數據的,僅僅作爲鏈表的頭節點。它的add()、get()、remove()方法就是對雙向鏈表的操作。它通過雙向鏈表地特性,重新實現了listIterator(int index)方法,定義內嵌的ListIterator類。
ArrayList的源代碼:
//size,isEmpty,get,set,iterator,和listIterator 等操作都是常量時間.add操作也接近常量時間。ArrayList實例都有一個屬性:capacity. capacity至少和size一樣大,它是自動增長的。它表示ArrayList可以存放的元素數目。
private static final int DEFAULT_CAPACITY = 10; //默認capacity.
private static final Object[] EMPTY_ELEMENTDATA = {};//capacity 就是這個 array buffer的大小
private transient Object[] elementData; //這就是arraylist最主要的元素:數組。
public void ensureCapacity(int minCapacity) ;//這個方法以及之後的一系列方法都是用來操作capacity 的,它們可以讓capacity 增長。
private void grow(int minCapacity) //這個方法展示了每次擴容擴多少,基本上相當於:newCapacity = oldCapacity + (oldCapacity >> 1);
public int indexOf(Object o) //順序查找對象。線性時間
public E get(int index) //索引獲取對象。常量時間
public E set(int index, E element)//線性時間
public boolean add(E e) //相當於線性時間
public void add(int index, E element) //插入,線性時間
public E remove(int index) //刪除,線性時間
LinkedList的源代碼:
//它相當於一個雙向鏈表,它實現了List, Deque,它可以當做stack、queue、double-queue來用。
transient Node<E> first; //頭結點
transient Node<E> last;//最後一個結點
private void linkFirst(E e) //將e連接至list頭部,成爲頭結點
void linkLast(E e) //將e連接至list尾部,成爲尾結點
void linkBefore(E e, Node<E> succ) //將e連接至succ之前
private E unlinkFirst(Node<E> f) //assert f爲頭結點,將f解開連接。f的下一個結點成爲頭結點。
private E unlinkLast(Node<E> l) //assert l爲尾結點,將l解開連接。
private E unlink(Node<E> x) //將x解開連接
public E getFirst() //獲取頭結點
public E getLast() //獲取尾結點
public E removeFirst() //同unlinkFirst,多了一個f是否爲空的判斷,可能拋出異常
public E removeLast() //
public void addFirst(E e) {linkFirst(e);}
public void addLast(E e) {linkLast(e);}
public boolean contains(Object o) //
public boolean add(E e) //連接到尾部 常量時間
public boolean remove(Object o) //線性時間
public E set(int index, E element) //常量時間
public void add(int index, E element) //常量時間
public E remove(int index) //常量時間
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
通常來說:在添加和刪除元素時具有比ArrayList更好的性能。但在get與set方面弱於ArrayList。
下一篇:ArrayList 、LinkedList 單線程操作對比。