首先我们来看add()方法
public boolean add(E e) {
modCount++;//记录此列表被结构修改的次数
add(e, elementData, size);//调用私有的add方法
return true;
}
它调用了另一个私有的方法
private void add(E e, Object[] elementData, int s) {
//如果size等于存储数组的长度,调用grow()方法进行扩容
if (s == elementData.length)
elementData = grow();
//运行到此一定是容量足够的,将传入的对象赋值给存储数组,并记录现有元素的数量
elementData[s] = e;
size = s + 1;
}
那么我们再来看看grow()是怎么扩容的
private Object[] grow() {
//方法体内还调用了真正的扩容方法
return grow(size + 1);
}
private Object[] grow(int minCapacity) {
//minCapacity接收加入新元素后的size
//oldCapacity接收了原存储数组的长度
int oldCapacity = elementData.length;
//private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//一开始创建的长度为0的存储数组
//如果不是第一次调用,则扩容,并将原有数据复制到新数组中,并赋值给原有栈变量,返回存储数组
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);
}
//如果是第一次调用add方法,这时候会进入else,新建一个长度为10的数组并返回
else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
获取新长度的方法,一般情况下是增加为原来的1.5倍
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// assert oldLength >= 0
// assert minGrowth > 0
//int prefGrowth首选增长值
//int minGrowth最小增长值
//int oldLength原长度
int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
//如果新长度小于可以增加的最大长度,则直接返回这个新长度
if (newLength - MAX_ARRAY_LENGTH <= 0) {
return newLength;
}
//返回
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 too large");
}
//如果最小增长值小于等于这个最大长度MAX_ARRAY_LENGTH=MAX_VALUE-8
if (minLength <= MAX_ARRAY_LENGTH) {
return MAX_ARRAY_LENGTH;
}
//否则返回能表示的最大值
//public static final int MAX_VALUE = 0x7fffffff;
return Integer.MAX_VALUE;
}