高效动态扩容arraylist采用1.5倍扩容策略(oldcapacity + oldcapacity>>1),初始容量为10,扩容时用system.arraycopy优化内存复制,严格索引检查确保安全。

手写一个高效的动态扩容 ArrayList,核心在于合理设计扩容策略、避免频繁内存复制,并保证常用操作(add、get、set、remove)的时间复杂度接近 O(1)(均摊)。下面从关键点出发,给出简洁、可落地的实现思路和代码骨架。
容量增长策略:用 1.5 倍扩容,而非翻倍
Java 官方 ArrayList 使用 oldCapacity + (oldCapacity >> 1)(即 1.5 倍),兼顾内存利用率与扩容频次。相比直接 ×2,它更节省空间,尤其在中等规模数据下减少浪费。
- 初始容量建议设为 10(与 JDK 一致,平衡小集合开销和首次扩容成本)
- 扩容时:新容量 = 旧容量 + 旧容量 / 2;若仍不够(如指定 minCapacity 极大),则直接取 minCapacity
- 注意整数溢出:用
newCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : newCapacity防越界
数组复制:用 System.arraycopy 替代循环赋值
这是性能关键——JVM 对 System.arraycopy 有深度优化(如汇编级内存块拷贝),比 for 循环快 3~5 倍,尤其在大数据量时。
- 扩容时只需一行:
System.arraycopy(elementData, 0, newData, 0, size); - 删除元素后搬移后续项,也优先用它:
System.arraycopy(elementData, index+1, elementData, index, size - index - 1);
懒加载与边界检查:只在必要时扩容,且每次访问都校验索引
不提前分配大数组,add 时才触发扩容;同时对所有 public 方法(get/set/remove)做 index >= size || index 检查,抛 <code>IndexOutOfBoundsException,行为与 JDK 严格对齐。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- add(E e):先确保容量够(
ensureCapacityInternal(size + 1)),再赋值并 size++ - add(int index, E e):先校验 index ∈ [0,size],再 ensure,再挪动元素,再插入
- remove(int index):校验 → 暂存 old → 挪动 → 置 null(帮助 GC)→ size--
辅助方法精简设计:复用逻辑,避免重复判断
把容量保障拆成两层:
-
ensureCapacityInternal(int minCapacity):处理 add 场景(含首次 add 的空数组初始化) -
ensureExplicitCapacity(int minCapacity):真正对比并触发 grow() -
grow(int minCapacity):专注计算新容量 + 数组复制 + 赋值
这样结构清晰,各司其职,也方便后续加监控或日志。
不复杂但容易忽略细节。照这个结构写,你的 ArrayList 就既有 JDK 的健壮性,又具备可调试、易扩展的基础。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










