我们来看下add方法(java 11及之后版本):
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length) {
elementData = this.grow();
}
elementData[s] = e;
this.size = s + 1;
}
public boolean add(E e) {
++this.modCount;
this.add(e, this.elementData, this.size);
return true;
}
public void add(int index, E element) {
this.rangeCheckForAdd(index);
++this.modCount;
int s;
Object[] elementData;
if ((s = this.size) == (elementData = this.elementData).length) {
elementData = this.grow();
}
System.arraycopy(elementData, index, elementData, index + 1, s - index);
elementData[index] = element;
this.size = s + 1;
}
因为一开始数组的默认长度是0,调用add方法时会调用grow方法。
private Object[] grow(int minCapacity) {
int oldCapacity = this.elementData.length;
if (oldCapacity <= 0 && this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return this.elementData = new Object[Math.max(10, minCapacity)];
} else {
int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, oldCapacity >> 1);
return this.elementData = Arrays.copyOf(this.elementData, newCapacity);
}
}
private Object[] grow() {
return this.grow(this.size + 1);
}
可见第一次调用add时数组会将长度从0扩展到10。当ArrayList中的元素个数超过数组的容量时,就会创建一个新的数组,容量为原来的1.5倍,然后通过Arrays.copyOf方法把原来数组中的元素复制到新数组中。
这里提一下grow方法中的位运算oldCapacity >> 1——按位右移一位。它等同于除以2。
例:1000(8) 0100(4) 0010(2)