1. 程式人生 > >ArrayList、Vector、LinkedList

ArrayList、Vector、LinkedList

xpl oid dom alt sta 鏈表 src exc onu

技術分享圖片

一、ArrayList分析

1.類和構造方法

public class ArrayList<E> extends AbstractList<E>  //可以看到其父類是AbstractList
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    private static final int
DEFAULT_CAPACITY = 10; //默認數組長度
//用於空實例的共享空數組實例。
private static final Object[] EMPTY_ELEMENTDATA = {}; //底層是Object類型的數組
//共享空數組實例用於默認大小的空實例。我們將其與EMPTY_ELEMENTDATA區別開來,以便知道當添加第一個元素時膨脹多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//存儲ArrayList元素的數組緩沖區。
//ArrayList的容量是這個數組緩沖區的長度。
//當添加第一個元素時,任何帶有elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList將被擴展為DEFAULT_CAPACITY。 transient Object[] elementData;
// 非私有以簡化嵌套類訪問 private int size; //數組內數據元素的個數 public ArrayList(int initialCapacity) {
//我們在聲明實例的時候可以指定容量大小,若為0的話,則使用ELEMENTDATA作為默認數組。
if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public ArrayList() { //若不指定容量大小,則使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA作為默認數組 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(Collection<? extends E> c) { //也可以接收Clooection類型的變量,把裏面的元素拷貝到數組裏面 elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } }

2.add()方法

 public boolean add(E e) { //在存入數據前,先確保內部容量
ensureCapacityInternal(size
+ 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 默認容量10和當前容量取max } ensureExplicitCapacity(minCapacity); //校驗當前容量是否符合要求容量 } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); // 如果要求容量大於數組容量,就擴容 } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量 = 舊容量+舊容量的一半 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); // 把舊數據拷貝到新數組裏面 }

二、Vector分析(線程安全的)

1.類和構造方法

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

    protected Object[] elementData;

    protected int elementCount;

    protected int capacityIncrement;

    private static final long serialVersionUID = -2767605614048989439L;

    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
   
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
  
    public Vector() {
        this(10);
    }

    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }
}

2.add()方法

public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1); // 先校驗容量
        elementData[elementCount++] = e;
        return true;
}
private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity); //擴容
}
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

三、LinkedList

1.類和構造方法

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;
    transient Node<E> first; //頭結點
    transient Node<E> last;  //尾結點

    public LinkedList() {
    }    
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

 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;
        }
    }

}

2.add()方法

public boolean add(E e) {//add方法就是在鏈表的尾部加上一個結點
        linkLast(e);
        return true;
}
void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
}

3.get()方法

public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
}
private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
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;
        }
}

ArrayList、Vector、LinkedList