ArrayList和Vector的擴容機制


ArrayList和Vector都是繼承了相同的父類和實現了相同的接口。如下

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

兩者之間我認為主要有兩個卻別。
1、Vector中的public方法都添加了synchronized關鍵字,以確保方法同步。
2、內部屬性不同,這也是導致擴容方式不同的原因所在。

我現在來說第二條,
ArrayList有兩個屬性,存儲數據的數組elementData,和存儲記錄數目的size。
Vector有三個屬性,存儲數據的數組elementData,存儲記錄數目的elementCount,還有擴展數組大小的擴展因子capacityIncrement。

先來看ArrayList的擴展方法 

    public void ensureCapacity(int minCapacity) {  
    modCount++;//父類中的屬性,記錄集合變化次數  
    int oldCapacity = elementData.length;  
    if (minCapacity > oldCapacity) {  
        Object oldData[] = elementData;  
        int newCapacity = (oldCapacity * 3)/2 + 1;  
            if (newCapacity < minCapacity)  
        newCapacity = minCapacity;  
        elementData = (E[])new Object[newCapacity];  
        System.arraycopy(oldData, 0, elementData, 0, size);  
    }  
       }  

重構下看起來更方便

    public void ensureCapacity(int minCapacity) {  
    modCount++;//父類中的屬性,記錄集合變化次數  
    int oldCapacity = elementData.length;  
    if (minCapacity > oldCapacity) {//擴容的條件,數組需要的長度要大於實際長度  
        Object oldData[] = elementData;  
        int newCapacity = ((oldCapacity * 3)/2 + 1)<minCapacity?minCapacity: ((oldCapacity * 3)/2 + 1);  
           elementData = (E[])new Object[newCapacity];  
        System.arraycopy(oldData, 0, elementData, 0, size);  
    }  
       }  

 可以看到,再滿足擴容條件時,擴展后數組大小為((原數組長度*3)/2+1)與傳遞參數中較大者

再看看Vector的擴容方法 

    public synchronized void ensureCapacity(int minCapacity) {  
        modCount++;//父類中的屬性,記錄集合變化次數  
        ensureCapacityHelper(minCapacity);  
        }  
     private void ensureCapacityHelper(int minCapacity) {  
        int oldCapacity = elementData.length;  
        if (minCapacity > oldCapacity) {//擴容的條件,數組需要的長度要大於實際長度  
            Object[] oldData = elementData;  
            int newCapacity = (capacityIncrement > 0) ?  
            (oldCapacity + capacityIncrement) : (oldCapacity * 2);  
                if (newCapacity < minCapacity) {  
            newCapacity = minCapacity;  
            }  
            elementData = new Object[newCapacity];  
            System.arraycopy(oldData, 0, elementData, 0, elementCount);  
        }  
        }  

可以看到,相對於ArrayList的擴容方法,這個方法被一分為2,老實說我更喜歡這樣,方法的職責更加明確。

int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2);

當擴容因子大於0時,新數組長度為原數組長度+擴容因子,否子新數組長度為原數組長度的2倍。

if (newCapacity < minCapacity) {newCapacity = minCapacity;}

將上面生成的新數組長度與傳遞的參數要求長度作比較,較大者為最終的新長度。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM