ArrayList动态扩容机制(长度可变原理)
//成员变量
//ArrayList 的默认初始容量,如果没有显式指定容量,则使用这个值
private static final int DEFAULT_CAPACITY = 10;
//定义一个空数组,空参构造器返回该数组,以及扩容的时候用到
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//size 是当前 ArrayList 中的元素数量,初始化为 0
private int size;
//ArrayList底层的数组,如果使用 ArrayList 的默认构造器时(默认构造器就是创建集合容器时不带参数),它的初始容量就是 0
transient Object[] elementData;
// 是一个常量,表示可以创建的最大数组大小
//Integer.MAX_VALUE 是 2^31 - 1,即最大的正整数。减去 8 是为了留出一些空间,避免在某些情况下(如内存分配)出现溢出或其他问题
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
---------------------------------------------------------------------
//add方法
public boolean add(E e) { //将元素 e 添加到 ArrayList 中
//这个方法用于确保 ArrayList 有足够的容量来存储新添加的元素
ensureCapacityInternal(size + 1);
// 会将元素 e 放到 elementData 数组的索引size位置(例如:添加第一个元素时,就是把元素放到0号索引位置),然后再把size的长度加1
elementData[size++] = e;
return true; //该方法总是返回true(异常除外),表示元素成功添加到ArrayList中
}
---------------------------------------------------------------------
//ensureCapacityInternal方法,add方法里面调用了该方法
//minCapacity表示所需的最小容量
private void ensureCapacityInternal(int minCapacity) {
//ensureExplicitCapacity方法负责调整内部数组的实际容量
//calculateCapacity方法负责计算所需新容量
//elementData:当前数组
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
----------------------------------------------------------------------
//calculateCapacity方法,ensureCapacityInternal方法里调用了该方法
//计算所需新容量
private static int calculateCapacity(Object[] elementData,int minCapacity) {
//检查 elementData 是否为空的默认数组
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//如果是,返回默认容量和所需最小容量中的较大值
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
//否则,返回所需的最小容量
return minCapacity;
}
-----------------------------------------------------------------------
//ensureExplicitCapacity方法,ensureCapacityInternal方法里调用了该方法
//调整内部数组的实际容量
private void ensureExplicitCapacity(int minCapacity) {
//增加修改计数
modCount++; //modCount是为了确保集合在被迭代时的安全性和一致性
//如果所需容量大于当前数组长度,则调用 grow 方法
//即minCapacity如果大于当前数组的长度(),则说明当前数组容量不足以容纳所需的最小容量,需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity); //调用 grow 方法来扩展数组的容量
}
-----------------------------------------------------------------------
//grow方法,ensureExplicitCapacity方法里调用了该方法
//扩展内部数组 elementData 的容量,以确保它能够容纳至少 minCapacity 个元素
private void grow(int minCapacity) {
int oldCapacity = elementData.length; // 获取旧容量(即元素的数量)
//利用位移运算符'>>'计算旧容量的 1.5 倍
//oldCapacity >> 1 : oldCapacity 的二进制向右移动一位,从而实现除以2的效果, 相当于oldCapacity/2,
int newCapacity = oldCapacity + (oldCapacity >> 1); //计算新容量
//如果计算出的新容量小于所需的最小容量 minCapacity,则将新容量设置为 minCapacity
if (newCapacity - minCapacity < 0) //确保新容量满足最小需求:
newCapacity = minCapacity;
//检查新容量(newCapacity)是否超过了最大数组大小 MAX_ARRAY_SIZE
//如果超过,则调用 hugeCapacity 方法来处理这种情况,通常是为了避免内存溢出
if (newCapacity - MAX_ARRAY_SIZE > 0) //限制最大容量
newCapacity = hugeCapacity(minCapacity);
// 使用 方法创建一个大小为 newCapacity的新数组,并将 elementData 中的所有元素复制到新数组中。elementData 引用被更新为指向这个新数组
elementData = Arrays.copyOf(elementData, newCapacity); //复制数组
}
----------------------------------------------------------------------
//hugeCapacity方法,grow方法里调用了该方法
//这个方法用于处理非常大的数组容量
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // 检查最小容量是否为负数
throw new OutOfMemoryError(); // 如果是,抛出内存不足错误
//三元表达式
return (minCapacity > MAX_ARRAY_SIZE) ? //如果所需容量超过最大数组大小
Integer.MAX_VALUE : // 如果是,就返回最大整数值,表示无法满足需求
MAX_ARRAY_SIZE; // 否则,返回最大数组大小
}