大致步骤:
1.先将minCapacity=size+1,判断是否是第一次插入值,若elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA(即初始化ArrayList时未指定初始化大小,或者指定的大小为0)则将minCapacity替换为DEFAULT_CAPACITY,即10
2.判断是否需要扩容:判断minCapacity(只有给未初始化设定大小或设定为0的ArrayList第一次添加值时会是10,其余都是size+1)与elementData.length比较,若大于elementData.length,则进行扩容
3.扩容大小第一阶段判断:将elementData.length * 1.5与minCapacity比较取得最大值newCapacity
4.扩容大小第二阶段判断:若newCapacity大于MAX_ARRAY_SIZE,则判断minCapacity是否大于MAX_ARRAY_SIZE,
大于则newCapacity=Integer.MAX_VALUE,不然就newCapacity=MAX_ARRAY_SIZE
5.令elementData = Arrays.copyOf(elementData, newCapacity);
注:(MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8,Integer.MAX_VALUE=2<<31 -1)
6.设置elementData[size]的值为新插入的值,并将size++
结论:需要特别注意的是初始化ArrayList时未指定初始化大小或指定大小为0时,数组的length都是0,这样的ArrayList第一次插入值需要做特殊处理
第一步的判断会获得minCapacity=DEFAULT_CAPACITY=10的值
第二步判断需要扩容
第三步判断newCapacity=10
第四步判断不成立
故在初始化ArrayList时建议手动指定大小
java8源码:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return true (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
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;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
ArrayList在Java中是有顺序的,其添加元素时会保持插入顺序。当未指定初始化大小或指定大小为0时,首次添加元素会进行特殊处理,扩容至10。在添加过程中,如果需要扩容,会将当前容量扩大1.5倍,确保能容纳更多元素。当扩容超过MAX_ARRAY_SIZE时,容量会调整到Integer.MAX_VALUE。因此,初始化ArrayList时建议手动指定大小以避免不必要的扩容。
5709

被折叠的 条评论
为什么被折叠?



