Java ArrayList擴容機制
阿新 • • 發佈:2021-07-20
- ArrayList中維護了一個Object型別的資料,elementData
-
transient Object[] elementData;
-
//transient表示該物件不會被序列化(序列化——把Java物件轉換為位元組序列的過程)
-
當建立ArrayList物件時,如果使用的是無參構造器,則初始elementData容量為0,第一次新增,則擴容為10,如果需要再次擴容,則擴容為elementData為1.5倍
-
如果使用的是指定大小的構造器,則初始化elementData容量為指定大小,如果需要擴容,則直接擴容為elementData為1.5倍
通過下列示例來說明該機制
package gather.collection.list; import java.util.ArrayList; @SuppressWarnings({"all"})//抑制警告 /** * @Author Blueshadow * @Date 2021/7/20 11:00 * @Version 1.0 */ public class list { public static void main(String[] args) { ArrayList list = new ArrayList();//elementData陣列初始大小為0 for (int i = 0; i < 10 ; i++) { list.add(i); } list.add(100); list.add(200); list.add(null); for (Object object : list) { System.out.println(object); } } }
底層原始碼說明
第一次初始化,建立了一個名為elementData的Object型別的陣列,該陣列可以存放多種型別的資料,主要是通過包裝類來實現。
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
//private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//建立Object型別陣列
//建立了一個空陣列,並將陣列命名為 elemenrData
}
下一步:在執行list.add(1)時,會先進性判斷,是否需要擴容,然後再執行賦值操作。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 判斷Increments modCount!!
elementData[size++] = e;//賦值操作
return true;
}
下一步:判斷是空,則給陣列賦予一個最小容量,第一次add,最小容量為minCapacity。
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//先確定elementData是否是一個空陣列:
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//先確定最小容量minCapacity(第一次擴容為10)
}
ensureExplicitCapacity(minCapacity);//真正確定是否擴容
}
下一步:進行底層的擴容。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//記錄當前集合被修改的次數
// overflow-conscious code
if (minCapacity - elementData.length > 0)//如果elementDara容量不夠,就呼叫grow方法進行擴容
grow(minCapacity);//進行底層的擴容
}
第一次擴容最後一步:底層按照1.5倍進行擴容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//第一次oldCapacity=0
int newCapacity = oldCapacity + (oldCapacity >> 1);//原先陣列大小+原先陣列大小/2
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);//elementData={},使用該方法將newCapacity賦值給elementData
}