java ArrayList 原始碼解讀
阿新 • • 發佈:2021-08-01
java ArrayList 原始碼解讀
ArrayList 類有三個構造方法,分別為無參構造方法,傳int構造方法,和傳集合構造方法
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
其中無參構造方法初始化完成之後 建立一個空的Object陣列 名為 elementData
/** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
在第一次呼叫add的時候將 elementData 擴容為10;
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity);//拿到預設值 f返回最大值 } return minCapacity; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { //這裡傳入為 10 modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) //這時候初始化的時候elementData.length為0 minCapacity為10 呼叫 grow方法擴容 grow(minCapacity); }
此時elementData 長度為 10 可以存放 10個物件,當第11個物件被 add的時候,判斷是否需要擴容為true 則進入擴容邏輯,擴容jdk8 邏輯為 將elementData 陣列長度擴容為 原有長度的1.5倍,程式碼中提現為
int newCapacity = oldCapacity + (oldCapacity >> 1);
之後擴容邏輯不變
有參傳int構造方法int值為 初始化 elementData 陣列長度
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}