1. 构造方法的源代码解读
(1)无参构造
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }- 将elementData初始化为一个空数组;
- DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空数组({}),用于标记“尚未真正初始化”;
- 此时底层数组长度为 0,不会分配默认容量 10;
- 真正的容量(10)会在第一次调用 add() 时通过扩容机制分配
(2)指定初始容量的构造方法
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); } }- 初始容量> 0:创建指定大小的数组
- 初始容量 = 0:使用空数组EMPTY_ELEMENTDATA
- 初始容量< 0:抛出IllegalArgumentException异常
(3)使用集合构造
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }- 将集合转为Object数组,赋值给elementData
- 处理c.toArray()可能返回非Object[]类型的情况
- 如果集合为空,初始化为空数组
2. add()方法的源代码解读
public boolean add(E e) { ensureCapacityInternal(size + 1); //确保容量足够 elementData[size++] = e; //添加元素 return true; }计算最小所需容量
private static int calculateCapacity(Object[] elementData, int minCapacity) { //如果是无参构造的默认空数组,直接返回默认容量10 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }- 若是首次添加(底层数组为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,也就是为空),则 minCapacity 至少为 DEFAULT_CAPACITY(即 10);
确保底层数组有足够的内部容量
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }接着调用 ensureExplicitCapacity(),判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) { modCount++; // 最小所需容量 > 底层数组当前长度 → 容量不足,触发扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); }3. grow()方法的源代码解读
private void grow(int minCapacity) { // 获取当前底层数组的旧容量 int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容1.5倍 if (newCapacity - minCapacity < 0) newCapacity = minCapacity;当1.5倍扩容后仍小于所需最小容量时
直接使用所需最小容量
if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);//处理大容量 elementData = Arrays.copyOf(elementData, newCapacity); }
MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
超过则调用 hugeCapacity();