Vector 學習筆記

Vector 介紹

Vector實現了一種可增長的數組對象。它可以像數組一樣,使用index訪問元素。 Vector的大小可以根據需要增加或縮小,以適應Vector創建後添加和刪除項目的需要。Vector 通過維護 capacity 和 capacityIncrement 來優化存儲管理。capacity 的值大於等於Vector的size. Vector 創建後,Vector的存儲量將以塊( capacityIncrement那麼多)的形式增加。

Vector 和 ArrayList的相同點

看代碼:

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//省略
}
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//省略
}

看到沒有,他們繼承了同一個父類ArrayList,實現了同樣的接口 List, RandomAccess, Cloneable, java.io.Serializable。
那奇怪了,豈不是多餘嗎?不是的。往下看:

Vector 和 ArrayList的不同點

第一個不同點,就是他們擴容的方式。ArrayList擴容比較大氣,根據當前的容量來。也就是:newCapacity = oldCapacity + (oldCapacity >> 1);

ArrayList的擴容方式:

    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比較摳門,每次只增加那麼一點點。capacityIncrement 指定的那麼多。
Vector的擴容方式:

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

那爲什麼Vector那麼扣呢?我覺得是有原因的。Vector和ArrrayList都實現了List接口,Vector用關鍵字 synchronized 修飾了所有的 操作方法,以做到同步。 以remove()方法來說:

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

看看Vector的實現,它在方法內調用的removeElement是使用了synchronized 修飾了的:

    public boolean remove(Object o) {
        return removeElement(o);
    }

    public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    

他們的size計算方式不一樣
對應ArrayList.他會有個數組 elementData。 還會有一個屬性 size。
在執行add方法的時候,如果成功,會對size進行加一操作。

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

但是對於Vector來時,就沒有size這個屬性了。它只有一個elementCount屬性。它在添加一個元素的時候,先判斷是否需要擴容,然後對 elementCount 執行加1操作。

    /**
     * Sets the size of this vector. If the new size is greater than the
     * current size, new {@code null} items are added to the end of
     * the vector. If the new size is less than the current size, all
     * components at index {@code newSize} and greater are discarded.
     *
     * @param  newSize   the new size of this vector
     * @throws ArrayIndexOutOfBoundsException if the new size is negative
     */
    public synchronized void setSize(int newSize) {
        modCount++;
        if (newSize > elementCount) {
            ensureCapacityHelper(newSize);
        } else {
            for (int i = newSize ; i < elementCount ; i++) {
                elementData[i] = null;
            }
        }
        elementCount = newSize;
    }
       
   /**
     * Adds the specified component to the end of this vector,
     * increasing its size by one. The capacity of this vector is
     * increased if its size becomes greater than its capacity.
     *
     * <p>This method is identical in functionality to the
     * {@link #add(Object) add(E)}
     * method (which is part of the {@link List} interface).
     *
     * @param   obj   the component to be added
     */
   public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }

Vector 和 ArrayList相比,還多了一個setSize(int newSize) 操作。就是根據給定的siz大小,如果比現有的elementCount大,就去擴容,如果比現有的elementCount小,就以爲着要搞清洗工作了,就是把超過的元素移出去啦。

    /**
     * Sets the size of this vector. If the new size is greater than the
     * current size, new {@code null} items are added to the end of
     * the vector. If the new size is less than the current size, all
     * components at index {@code newSize} and greater are discarded.
     *
     * @param  newSize   the new size of this vector
     * @throws ArrayIndexOutOfBoundsException if the new size is negative
     */
    public synchronized void setSize(int newSize) {
        modCount++;
        if (newSize > elementCount) {
            ensureCapacityHelper(newSize);
        } else {
            for (int i = newSize ; i < elementCount ; i++) {
                elementData[i] = null;
            }
        }
        elementCount = newSize;
    }

Vector還有cpacity()和size()方法,前者表示在不擴容的情況下,可以放多少對象進去。就是它持有對象數組的長度。
size()就是返回一個計數器elementCount.elementCount記錄了到添加了多少個對象進去。

    /**
     * Returns the current capacity of this vector.
     *
     * @return  the current capacity (the length of its internal
     *          data array, kept in the field {@code elementData}
     *          of this vector)
     */
    public synchronized int capacity() {
        return elementData.length;
    }

    /**
     * Returns the number of components in this vector.
     *
     * @return  the number of components in this vector
     */
    public synchronized int size() {
        return elementCount;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章