JDK17 ArrayList源码分析
//容器默认的初始化容量
private static final int DEFAULT_CAPACITY = 10;
//用于空实例的共享空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};
//共享空数组实例,用于默认大小的空实例。我们将其与EMPTY_ELEMENTDATA区分开来,以便知道在添加第一个元素时膨胀多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//数组缓冲区,存储数组列表中的元素。数组列表的容量是这个数组缓冲区的长度。当第一个元素被添加时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData;
//数组列表的大小(它当前包含的元素的数量)。
private int size;
默认的三个构造函数
/**
* 按照给定的大小初始化elementData
*/
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);
}
}
/**
* 无参的构造方法,在第一次使用add方法时,会将elementData膨胀为大小为10的数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 按照指定的集合初始化elementdata
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
add方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 用来确保当前数组不会越界,在满足条件时进行膨胀
elementData[size++] = e;
return true;
}
ensureCapacityInternal方法
private void ensureCapacityInternal(int minCapacity) {
//calculateCapacity:如果是调用无参的构造方法来构造的对象,首次添加时则默认返回了DEFAULT_CAPACITY:大小为10,否则就返回在原size+1的值
//ensureExplicitCapacity:用来确保当前存储数组elementData长度是否已经到达最大,并在一定条件下进行扩容
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
calculateCapacity,首次添加的时候,增加为默认大小10
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
ensureExplicitCapacity方法:用来确保当前存储数组elementData长度是否已经到达最大,并在一定条件下进行扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
// 如果已经到达最大,则进行扩容
grow(minCapacity);
}
关键方法grow()
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)];
}
}
ArraysSupport的newlength方法
public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// preconditions not checked because of inlining
// assert oldLength >= 0
// assert minGrowth > 0
// 新的长度为原来的1.5倍或者为原来的长度加上minGrowth的长度
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
return prefLength;
} else {
// put code cold in a separate method
return hugeLength(oldLength, minGrowth);
}
}
//超出长度调用的方法
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;
}
}