ArrayList是如何擴容的?


首先有三種構造方法,空參,指定大小,和指定集合

public ArrayList();

public ArrayList(Collection<? extends E> c)

public ArrayList(int initialCapacity)

后兩種通過創造對象,或指定大小來初始化內部數據即可。

空參的時候,默認數組長度是0,也就是初始化數組長度為0

添加數據后,


public boolean add(E e) { //確保內部容量(通過判斷,如果夠則不進行操作;容量不夠就擴容來確保內部容量)

 

     ensureCapacityInternal(size + 1); // ①Increments modCount!!

 

     elementData[size++] = e;//②

 

     return true;

 

 }

 

① ensureCapacityInternal方法名的英文大致是“確保內部容量”,size表示的是執行添加之前的元素個數,並非ArrayList的容量,容量應該是數組elementData的長度。ensureCapacityInternal該方法通過將現有的元素個數數組的容量比較。看如果需要擴容,則擴容。

②是將要添加的元素放置到相應的數組中。

根據傳入的最小需要容量minCapacity來和數組的容量長度對比,若minCapactity大於或等於數組容量,則需要進行擴容。

綜上所述,ArrayList的空參構造方法相當於在沒指定initialCapacity時就是會使用延遲分配對象數組空間,當第一次插入元素時才分配10(默認)個對象空間。假如有20個數據需要添加,那么會分別在第一次的時候,將ArrayList的容量變為10 ;之后擴容會按照1.5倍增長。也就是當添加第11個數據的時候,Arraylist繼續擴容變為10*1.5=15當添加第16個數據時,繼續擴容變為15 * 1.5 =22個。

 

如果通過無參構造的話,初始數組容量為0,當真正對數組進行添加時,才真正分配容量。每次按照1.5倍(位運算)的比率通過copeOf的方式擴容。


/*
 *增加容量,以確保它至少能容納
 *由最小容量參數指定的元素數。
 * @param mincapacity所需的最小容量 */
private void grow(int minCapacity) { // overflow-conscious code
int oldCapacity = elementData.length; //>>位運算,右移動一位。 整體相當於newCapacity =oldCapacity + 0.5 * oldCapacity
 // jdk1.7采用位運算比以前的計算方式更快
int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0)
 newCapacity = minCapacity; //jdk1.7這里增加了對元素個數的最大個數判斷,jdk1.7以前是沒有最大值判斷的,MAX_ARRAY_SIZE 為int最大值減去8(不清楚為什么用這個值做比較)
if (newCapacity - MAX_ARRAY_SIZE > 0)
 newCapacity = hugeCapacity(minCapacity); // 最重要的復制元素方法
elementData = Arrays.copyOf(elementData, newCapacity);
 }


免責聲明!

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



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