Java ArrayList的扩容机制是怎样的?
·
Java ArrayList 的扩容机制是其核心特性之一,目的是在元素数量接近当前数组容量时,通过动态调整数组大小来保证新增元素有足够的存储空间。其底层扩容逻辑可总结为以下几个关键点:
1. 触发扩容的时机
当调用 add() 或 add(int index, E element) 等方法添加元素时,ArrayList 会先检查当前数组容量是否足够(即 size + 1 是否超过数组长度)。如果不足,则触发扩容。
2. 扩容的核心逻辑
扩容的核心步骤在 grow() 方法中实现,具体规则如下:
- 计算新容量:默认情况下,新容量 = 旧容量 + 旧容量的一半(即 扩容为原来的 1.5 倍)。
实现方式为位运算:int newCapacity = oldCapacity + (oldCapacity >> 1)(oldCapacity >> 1等价于oldCapacity / 2,效率更高)。 - 特殊情况处理:
如果计算出的新容量仍小于实际需要的最小容量(例如初始容量为 0 时添加大量元素),则直接将新容量设为“所需最小容量”。
3. 扩容的具体过程
- 检查容量需求:通过
ensureCapacityInternal()确定所需的最小容量(minCapacity = size + 1)。 - 判断是否需要扩容:若
minCapacity超过当前数组长度,则调用grow()方法。 - 创建新数组并复制元素:通过
Arrays.copyOf()生成一个新容量的数组,并将原数组中的元素复制到新数组中,最后替换原数组引用。
4. 初始容量的特殊处理
- 若使用无参构造器
new ArrayList(),初始数组为空(EMPTY_ELEMENTDATA),第一次添加元素时会直接扩容到默认容量 10。 - 若指定初始容量(如
new ArrayList(5)),则初始数组长度为指定值,后续扩容仍按 1.5 倍规则执行。
示例说明
假设初始容量为 10,扩容过程如下:
- 当添加第 11 个元素时,旧容量为 10,新容量 = 10 + 5 = 15。
- 当添加第 16 个元素时,旧容量为 15,新容量 = 15 + 7 = 22(15 的一半为 7.5,取整数 7)。
- 若一次添加 20 个元素(初始为空数组),第一次扩容会直接使用所需容量 20(而非默认 10)。
总结
ArrayList 的扩容机制通过“按需动态扩容”实现了灵活的容量管理,默认以 1.5 倍方式扩容,平衡了内存占用和操作效率(复制元素的时间复杂度为 O(n),但扩容频率较低)。如果能预估元素数量,建议在初始化时指定合适的容量,减少扩容次数以优化性能。
更多推荐


所有评论(0)