arraylist扩容实际使用oldcapacity + (oldcapacity >> 1)实现1.5倍增长,等价于整数除法向下取整;空参构造首次add设容量为10,位运算优化性能且避免浮点误差。

Java 中 ArrayList 底层数组扩容时,并不是简单地“乘以 1.5”,而是通过位运算高效实现等价的 oldCapacity + oldCapacity >> 1,即 oldCapacity * 1.5 向下取整。
扩容公式的实际计算方式
源码中关键逻辑如下(JDK 8+):
int newCapacity = oldCapacity + (oldCapacity >> 1);
这等价于:newCapacity = oldCapacity + (oldCapacity / 2)(整数除法,自动向下取整)
例如:
- 原容量为 10 →
10 + (10 >> 1) = 10 + 5 = 15 - 原容量为 7 →
7 + (7 >> 1) = 7 + 3 = 10(因为7 >> 1是 3,不是 3.5) - 原容量为 1 →
1 + (1 >> 1) = 1 + 0 = 1(此时不会增长,但首次添加元素时会直接设为默认容量 10)
初始容量和首次扩容的特殊情况
空参构造的 ArrayList 初始底层数组为 null,第一次添加元素时才真正初始化:
- 首次
add()触发扩容 → 容量设为 10(不是 0 × 1.5) - 后续扩容才按
old + old>>1计算 - 如果用带参构造(如
new ArrayList(5)),则初始容量为 5;下次扩容就是5 + 2 = 7
为什么用位运算而不是直接写 * 1.5?
这是为了性能优化:
-
oldCapacity >> 1是 CPU 级别的快速右移操作,比浮点乘法或整数乘除更快 - 避免引入浮点数、类型转换和舍入误差
- 语义清晰:对正整数而言,
>>就是无符号右移,等价于除以 2 并向下取整
扩容后还要考虑最小容量要求
扩容计算只是第一步。ArrayList 还要确保新容量不小于「所需最小容量」(比如当前 size + 1):
- 若计算出的
newCapacity (例如大量 add 导致需一次扩很大),则直接取 <code>minCapacity - 若
minCapacity太大(超过MAX_ARRAY_SIZE),还会触发溢出处理(如分配Integer.MAX_VALUE或抛OutOfMemoryError)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











