arraylist扩容本质是旧容量加其右移一位的值,即newcapacity = oldcapacity + (oldcapacity >> 1),等效于向下取整的1.5倍;首次扩容强制设为10,且需满足最小容量与溢出校验。

ArrayList 的扩容不是简单地乘以 1.5,而是通过位运算实现的等效计算:新容量 = 旧容量 + (旧容量 >> 1),也就是“旧容量加上它右移一位的值”。这在整数运算中恰好等于 旧容量 × 1.5 向下取整。
为什么用位运算代替乘法?
位移比浮点或整数乘法更高效,JVM 层面可直接映射为 CPU 指令。而且 ArrayList 要求容量是 int 类型,必须是整数,所以不能用 1.5f 这样的浮点数。
- 例如:旧容量是 10 → 10 >> 1 = 5 → 新容量 = 10 + 5 = 15
- 旧容量是 7 → 7 >> 1 = 3(整数除法截断)→ 新容量 = 7 + 3 = 10
- 旧容量是 1 → 1 >> 1 = 0 → 新容量 = 1 + 0 = 1(但实际会强制设为 10,这是首次扩容的特殊逻辑)
扩容的完整判断逻辑
add 方法触发扩容时,并非每次都走 1.5 倍规则。源码中关键逻辑如下:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 如果当前数组为默认空数组(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA),首次 add 会直接分配容量为 10
- 否则,按 newCapacity = oldCapacity + (oldCapacity >> 1) 计算
- 若计算结果仍小于所需最小容量(minCapacity),则直接取 minCapacity
- 若 newCapacity 溢出(超过 Integer.MAX_VALUE),会调用 hugeCapacity() 处理(可能抛 OutOfMemoryError 或设为 Integer.MAX_VALUE)
注意边界情况
位运算对奇数和小数值有截断效应,所以扩容不是严格的数学 1.5 倍,而是“不低于 1.5 倍向下取整”的整数策略:
- 容量 1 → 1 → 1(不扩容,直到 add 第二个元素才触发)
- 容量 2 → 2 + 1 = 3
- 容量 3 → 3 + 1 = 4
- 容量 4 → 4 + 2 = 6
- 容量 5 → 5 + 2 = 7
源码对应位置(JDK 8+)
核心逻辑在 grow(int minCapacity) 方法中:
int newCapacity = oldCapacity + (oldCapacity >> 1);
这一行就是“1.5 倍扩容”的本质实现。后续还有校验和赋值操作,但增长比例就由这行决定。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










