ArrayList扩容在add前检查容量,触发条件为size+1>当前容量;新容量按oldCapacity + (oldCapacity>>1)计算(≈1.5倍),不足时取所需最小值,扩容依赖Arrays.copyOf,时间复杂度O(n)。

ArrayList 的扩容不是简单地用当前容量乘以 1.5,而是通过位运算高效实现“旧容量 + 旧容量 / 2”,即等价于 oldCapacity + (oldCapacity >> 1)。
底层扩容公式(JDK 8+)
当元素数量超过当前数组长度时,ArrayList 调用 grow() 方法扩容,核心逻辑是:
- 新容量 = 旧容量 + (旧容量 右移 1 位) → 即 newCapacity = oldCapacity + (oldCapacity >> 1)
- 这等价于 oldCapacity * 1.5(仅对非负整数成立),因为右移 1 位相当于无符号整除 2(向下取整)
- 例如:oldCapacity = 10 → 10 + (10 >> 1) = 10 + 5 = 15;oldCapacity = 7 → 7 + (7 >> 1) = 7 + 3 = 10
为什么要用位运算而不是直接写 * 1.5?
因为:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 性能更高:位运算比浮点乘法和类型转换更快,且避免了 double 运算和强制转型
- 结果确定:整数右移天然截断小数部分,无需 Math.floor() 或强制转 int
- 符合 JVM 优化习惯:HotSpot 对此类模式有良好识别和优化支持
完整扩容逻辑(含边界处理)
实际代码中还包含最小容量保障和溢出检查:
立即学习“Java免费学习笔记(深入)”;
- 先计算理论新容量:
int newCapacity = oldCapacity + (oldCapacity >> 1); - 若新容量仍小于所需最小容量(minCapacity),则直接设为 minCapacity
- 若 newCapacity 溢出(hugeCapacity(minCapacity) 返回
Integer.MAX_VALUE或抛OutOfMemoryError
注意:初始容量不参与该公式
首次 add 时,若未指定初始容量(即 new ArrayList<>()),内部数组为 EMPTY_ELEMENTDATA,第一次扩容会直接设为默认容量 10,不走 1.5 倍逻辑。

















