ArrayList 中定义了一个 elementData 他是一个object的数组
当创建一个ArrayList数组的时候如果使用的是无参构造,那么初始的elementdata 的容量则为0,第一次添加的,则扩容elementdata为10,如需在扩容则扩容elementdata的1.5倍
DEFAULTCAPACITY_EMPTY_ELEMENTDATA={}
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
如果使用的是指定大小的构造器,则初始容量为指定大小,如需扩容则直接扩容1.5倍
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);
}
}
当创建完elementdata后代码会去执行ensureCapacityInternal方法 用来验证是否需要扩容
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
elementData 等空的时候会进入判断 和DEFAULT_CAPACITY进行比较取最大值 因为是第一次添加数据所以minCapacity的值完10,然后会进入ensureExplicitCapacity方法
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
此时,minCapacity - elementData.length > 0成立,所以会进入 grow(minCapacity) 方法。
当add第2个元素时,minCapacity 为2,此时e lementData.length(容量)在添加第一个元素后扩容成 10 了。此时,minCapacity - elementData.length > 0 不成立,所以不会进入 (执行)grow(minCapacity) 方法。
添加第3、4···到第10个元素时,依然不会执行grow方法,数组容量都为10。
直到添加第11个元素,minCapacity(为11)比elementData.length(为10)要大。进入grow方法进行扩容。
modCount代表的是扩容的次数
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
oldCapacity 会被赋值完当前数组的长度,newCapacity 会以当前数组容量去+上当前数组容量位移1 则代表当前容量的1.5倍,然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
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);
}