java基礎:Vector/Stack — 原始碼分析

Hiway發表於2019-01-07

其他更多java基礎文章:
java基礎學習(目錄)


概述

雖然,Vector和Stack在我們的程式設計中,使用的比較少,至少我使用的比較少,一般情況下,我都是傾向於使用List來儲存一些同型別的元素。
Vector的內部實現和ArrayList的內部實現基本一致,內部都是藉助於陣列來實現的,主要區別是方法加了synchronized關鍵字,實現了執行緒安全。
Stack是繼承自Vector來實現的,而且Stack只是在Vector的基礎上提供了幾個方法罷了,就不展開講解了。

Vector

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
複製程式碼

Vector繼承了AbstractList抽象類並實現了List、RandomAccess、Cloneable、Serializable介面,和ArrayList一樣。

基礎欄位

    protected Object[] elementData;
    protected int elementCount;
    protected int capacityIncrement;
複製程式碼
  • elementData:陣列,用來存放元素的
  • elementCount:記錄陣列中已經儲存了的資料的個數
  • capacityIncrement:自動擴容的大小,即當陣列滿了之後,就新增capacityIncrement個空間裝載元素,如果capacityIncrement<=0,則擴容時就擴容到目前Vector容量的兩倍

方法細節

add方法

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    
    //在指定位置新增元素
    public void add(int index, E element) {
        insertElementAt(element, index);
    }

    public synchronized void insertElementAt(E obj, int index) {
        modCount++;
        //有效性檢查
        if (index > elementCount) {
            throw new ArrayIndexOutOfBoundsException(index
                                                     + " > " + elementCount);
        }
        //檢查是否需要擴容,若需要,則進行擴容
        ensureCapacityHelper(elementCount + 1);
        //拷貝
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
        elementData[index] = obj;
        elementCount++;
    }
    
    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        //當陣列已滿,則呼叫grow函式來對陣列進行擴容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //擴容的大小由capacityIncrement決定,如果capacityIncrement<=0,則擴容到目前陣列的兩倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        //檢查是否newCapacity溢位了
        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;
    }
複製程式碼

基本沒什麼難度,增加了synchronized關鍵字,實現了執行緒安全,其他跟ArrayList的基本一樣。可以參考java基礎:ArrayList — 原始碼分析
唯一有點不同的是,Vector的擴容預設是擴容為2倍,若capacityIncrement不為0,則擴容capacityIncrement的值。ArrayList則是擴容為1.5倍。

總結

  1. Vector是基於陣列來實現的
  2. Vector是執行緒安全的,ArrayList是執行緒不安全的。
  3. Vector實現基本與ArrayList一樣

相關文章