问题:
刷面经,博客输出,加深印象,2025.3.4 希望毕业前找到工作。
扩容流程:
源码解析:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* Default initial capacity.
* 默认初始化容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
*
* Shared empty array instance used for empty instances.
* 创建空数组实例,默认容量为空
*/
private static final Object[] EMPTY_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.
* 创建空数组实例,数组默认容量是10,但实际数组是空的,只有第一次添加元素后,才会真正
* 是默认容量
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*
* 说白了就是真正存储数据的数组
* 空的数组 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
*当添加第一个元素时, elementData == DEFAULT_CAPACITY
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
//初始实际数组为空,但是默认容量是10的数组
//当添加第一个元素时,才会真正是容量是10
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Increases the capacity of this {@code ArrayList} instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) {
modCount++;
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
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
//oldCapacity大于0,一定是已经初始化过了,
//所以,这里判断的是是否已经初始化过或者是不是第一次添加元素
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//计算出一个新的长度
int newCapacity = ArraysSupport.newLength(oldCapacity,
//比如是10个已经满了,再添加1个 11 - 10=1,也就是最小必须得增加1个
minCapacity - oldCapacity, /* minimum growth */
// oldCapacity / 2 比如默认是10 ,那推介在增加10/2个 也就说扩容1.5倍
oldCapacity >> 1 /* preferred growth */);
//复制新数组
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
//
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
private Object[] grow() {
//当前size =10,需要扩容,最小扩容为size + 1 = 10 +1
return grow(size + 1);
}
}
/*
oldLength: 旧容量
minGrowth: 最小增长长度,比如你需要再添加1个,那就是10+1=11
prefGrowth:推介增长量,让满足可以添加的情况下,再增加一些
*/
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// preconditions not checked because of inlining
// assert oldLength >= 0
// assert minGrowth > 0
//计算长度
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
//防止数组超出最大最小限制
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
//没有超出范围,我都是优先推介的范围
return prefLength;
} else {
//如果 推介范围超出了,则用最小范围
return hugeLength(oldLength, minGrowth);
}
}
//保证最小的长度,eg.10个已经满了,我需要再添加1个,也就是增加1个容量,即11
private static int hugeLength(int oldLength, int minGrowth) {
//旧长度+最小增长率=最小的扩容容量,刚刚满足好最小范围
int minLength = oldLength + minGrowth;
//防止超出范围
if (minLength < 0) { // overflow
throw new OutOfMemoryError(
"Required array length " + oldLength + " + " + minGrowth + " is too large");
} else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
return SOFT_MAX_ARRAY_LENGTH;
} else {
return minLength;
}
}