我們聲明一個初始容量為1的ArrayList〉肃冢看看在add時候到底發(fā)生了什么。
public class Main {
public static void main(String[] args) {
final ArrayList<String> objects = new ArrayList<>(1);
objects.add("A");
objects.add("B");
objects.add("C");
}
}
當(dāng)聲明的容量小于10時的情況
執(zhí)行第一個語句objects.add("A"),此時size是0捶码,執(zhí)行ensureCapacityInternal(1)。
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
calculateCapacity(elementData,1)或链,此時數(shù)組為空惫恼,所以return 10。調(diào)用ensureExplicitCapacity(10)澳盐。
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
10 > 0 調(diào)用grow(10)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
newCapacity - minCapacity = -10 < 0 ,所以newCapacity=10祈纯。elementData = Arrays.copyOf(elementData,10); elementData容量變?yōu)榱?0。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
無需擴容的情況
接下來執(zhí)行objects.add("B")叼耙。此時size是1腕窥,執(zhí)行ensureCapacityInternal(2)。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
calculateCapacity(elementData,2)筛婉,此時數(shù)組不為空簇爆,所以return 2。調(diào)用ensureExplicitCapacity(2)。
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
2-10 < 0 所以不需要grow入蛆,直接執(zhí)行上面的elementData[size++] = e响蓉。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
正常擴容情況
1.5倍擴容,將原來的數(shù)組整個拷貝過去安寺。
int newCapacity = oldCapacity + (oldCapacity >> 1);
elementData = Arrays.copyOf(elementData, newCapacity)
總結(jié)
- 當(dāng)我們new一個ArrayList的時候厕妖,初始容量為0,內(nèi)部表示為一個空數(shù)組挑庶。在一次add后言秸,容量為擴充為10。
- 我們可以自定義初始容量的大小迎捺,值得注意的是举畸,如果定義的容量小于10,在第一次add后凳枝,容量會擴充為10抄沮。
- 容量不夠時,按照1.5倍原容量大小擴容岖瑰,復(fù)制原容量數(shù)組的所有元素到新容量的數(shù)組去叛买。所以說擴容是一個比較昂貴的操作。我們可以根據(jù)需求設(shè)置初始容量蹋订。