提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
粗略来说,ArrayList每次扩容1.5倍左右,为何呢?
正常情况下,ArrayList的扩容公式是:int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
其中perGrowth = oldGrowth >> 1,所以当oldGrowth 为奇数时,perGrowth就会略小于oldGrowth的0.5倍。
一、看一下源码,便一目了然
/*
如有必要,增加此 ArrayList 实例的容量,以确保它至少可以容纳最小容量参数指定的元素数。
参数:
最小容量 – 所需的最小容量
*/
public void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) {
modCount++;
grow(minCapacity);
}
}
/*
增加容量以确保它至少可以容纳最小容量参数指定的元素数。
参数:
最小容量 – 所需的最小容量
抛出:
OutOfMemoryError – 如果最小容量小于零
*/
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
/*
在给定阵列的当前长度、首选增长值和最小增长值的情况下计算新的阵列长度。如果首选增长值小于最小增长值,则使用最小增长值代替它。如果当前长度和首选增长值的总和不超过 MAX_ARRAY_LENGTH,则返回该总和。如果当前长度和最小增长值的总和不超过 MAX_ARRAY_LENGTH,则 MAX_ARRAY_LENGTH 返回。如果总和没有溢出 int,则 Integer.MAX_VALUE 返回。否则, OutOfMemoryError 被抛出。
参数:
oldLength – 数组的当前长度(必须为非负数)
最小增长 – 阵列长度所需的最小增长(必须为正数)
prefGrowth – 数组长度的首选增长(如果小于 minGrowth)
返回:
数组的新长度
抛出:
OutOfMemoryError – 如果通过 oldLength 溢出增加 minGrowth 。
*/
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// assert oldLength >= 0
// assert minGrowth > 0
int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
if (newLength - MAX_ARRAY_LENGTH <= 0) {
return newLength;
}
return hugeLength(oldLength, minGrowth);
}