1 Add elements
ArrayList is based on array storage. The default array size is 10. When the capacity of adding elements is not enough, the capacity will be expanded. For the following code:
// 创建一个 ArrayList 对象
ArrayList<Integer> nums = new ArrayList<>();
// 向集合中添加元素
nums.add(1);
nums.add(2);
nums.add(3);
When executing new ArrayList(), call the ArrayList no-argument constructor
public ArrayList() {
// DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空的 Object 类型的数组,当添加第一个元素时,elementData 指向一个大小为 10 的数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
When the add() method is called
public boolean add(E e) {
// 当前元素个数+1,判断是否需要进行扩容操作
ensureCapacityInternal(size + 1);
// 将此元素添加到数组
elementData[size++] = e;
return true;
}
ensureCapacityInternal 方法
private void ensureCapacityInternal(int minCapacity) {
// 当第一次添加元素,条件成立
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 取最大值,DEFAULT_CAPACITY 的值为 10,minCapacity 第一次添加元素传入 1
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
ensureExplicitCapacity method
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 当容量不够时,进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
grow method
private void grow(int minCapacity) {
// 当前数组长度
int oldCapacity = elementData.length;
// 新的数组长度 = 当前数组长度 + (当前数组长度右移 1 位),第一次添加 newCapacity = 0
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 第一次添加元素,条件成立 0 - 10 < 0,赋值 newCapacity = 10,因此,调用无参构造方法默认数组大小为 10
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 调用 copyOf 方法,创建新的大小为 newCapacity 的数组,并将原来数组的元素拷贝到新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
2 delete elements
// 移除指定索引的元素
nums.remove(1);
remove method
public E remove(int index) {
// 检测指定的索引是否越界
rangeCheck(index);
modCount++;
// 获取待移除的元素,操作完成后返回
E oldValue = elementData(index);
// 计算出 index 之后元素的个数
int numMoved = size - index - 1;
if (numMoved > 0)
// 调用 arraycopy 方法将 index 之后的元素向前移动一位,将 index 位置的元素覆盖掉
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 将数组最后位置的值置为 null
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}