在調(diào)用add(E e)
時(shí),會(huì)調(diào)用ensureCapacityInternal(size + 1)
來(lái)確保數(shù)組有足夠的容量來(lái)新增元素端考。
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
ensureCapacityInternal(int mincapacity)
源碼如下弛房,該方法調(diào)用了calculateCapacity(elementData, minCapacity)
和ensureExplicitCapacity
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
其中calculateCapacity(elementData, minCapacity)
源碼如下
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 調(diào)用ArrayList的無(wú)參構(gòu)造函數(shù)开睡,elementData會(huì)指向這個(gè)DEFAULTCAPACITY_EMPTY_ELEMENTDATA空數(shù)組,
// 這時(shí)如果調(diào)用add就會(huì)進(jìn)入下面這個(gè)判斷
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
如果當(dāng)前數(shù)組為空數(shù)組(剛使用無(wú)參構(gòu)造函數(shù)創(chuàng)建完ArrayList鞭呕,往其添加元素時(shí))蛤育,則返回10,即最小的容量是10(剛創(chuàng)建完ArrayList葫松,第一次擴(kuò)容要求capacity最小是10)瓦糕。
ensureExplicitCapacity(int minCapacity)
源碼如下,大概邏輯是:如果當(dāng)前數(shù)組長(zhǎng)度達(dá)不到想要的minCapacity腋么,則調(diào)用grow擴(kuò)容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果要求的最小容量比當(dāng)前數(shù)組長(zhǎng)度大咕娄,即當(dāng)前數(shù)組長(zhǎng)度放不下了,就會(huì)調(diào)用grow擴(kuò)容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
grow(int minCapacity)
大概邏輯:計(jì)算新的數(shù)組長(zhǎng)度珊擂,為原來(lái)數(shù)組長(zhǎng)度的1.5倍圣勒,如果該值比要求的minCapacity小费变,則取minCapacity。
如果新數(shù)組長(zhǎng)度比MAX_ARRAY_SIZE大圣贸,則調(diào)用hugeCapacity獲取一個(gè)長(zhǎng)度挚歧。
最后調(diào)用Arrays.copyOf(elementData, newCapacity)
創(chuàng)建新數(shù)組并拷貝元素過(guò)去。
源碼如下
private void grow(int minCapacity) {
// 舊的數(shù)組長(zhǎng)度
int oldCapacity = elementData.length;
// >> 1是 右移一位吁峻,即除以2滑负。所以這句代碼意思是:newCapacity是oldCapacity的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果newCapacity比minCapacity還要小(剛創(chuàng)建完ArrayList用含,往其添加元素時(shí)會(huì)滿足這種情況)矮慕,則取minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果newCapacity比數(shù)組最大值MAX_ARRAY_SIZE大,則調(diào)用hugeCapacity獲取一個(gè)比較大的capacity
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 創(chuàng)建一個(gè)newCapacity大小的新數(shù)組啄骇,并將原來(lái)數(shù)組的元素拷貝過(guò)去
elementData = Arrays.copyOf(elementData, newCapacity);
}
hugeCapacity(int minCapacity)
大概邏輯:如果minCapacity比MAX_ARRAY_SIZE(Integer.MAX_VALUE-8)大痴鳄,則取Integer.MAX_VALUE,否則取MAX_ARRAY_SIZE缸夹。
源碼如下
private static int hugeCapacity(int minCapacity) {
// minCapacity小于0表示溢出超過(guò)int能表示的數(shù)字范圍
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
// 如果minCapacity大于MAX_ARRAY_SIZE(Integer.MAX_VALUE-8),則取nteger.MAX_VALUE夏跷,否則取MAX_ARRAY_SIZE(Integer.MAX_VALUE-8)
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}