跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

Java ArrayList 核心解析:原理、用法与扩容机制

Java ArrayList 基于动态数组实现,底层维护 Object[] 数组,支持随机访问且非线程安全。构造时可指定初始容量以减少扩容开销。常用操作涵盖添加、删除、获取及子列表截取,遍历支持普通循环、增强循环及迭代器。扩容机制默认初始容量 10,后续按 1.5 倍增长。适用于单线程读多写少场景,多线程需考虑同步方案。

竹影清风发布于 2026/3/24更新于 2026/10/2595 浏览
Java ArrayList 核心解析:原理、用法与扩容机制

Java ArrayList 核心解析

ArrayList 是 Java 集合框架中最常用的动态数组实现,底层维护一个 Object[] 数组(elementData),通过 size 变量记录当前有效元素个数。它实现了 List 接口,支持随机访问,同时具备 Cloneable 和 Serializable 特性。需要注意的是,ArrayList 不是线程安全的,在多线程环境下建议使用 Vector 或 CopyOnWriteArrayList。

一、ArrayList 的概念

ArrayList 是以泛型方式实现的动态顺序表,底层是一段连续的空间,容量可自动扩容。使用时必须实例化,适合大多数读多写少的场景。

ArrayList 结构示意

二、ArrayList 的使用

1. 构造 ArrayList

ArrayList 提供三种构造函数,根据实际需求选择初始容量能有效减少扩容带来的性能损耗。

方法说明
ArrayList()无参构造,默认容量为 10
ArrayList(Collection<? extends E> c)利用其他 Collection 构建
ArrayList(int initialCapacity)指定顺序表初始容量
1.1 无参构造方法
public static void main(String[] args) {
    // 创建一个空的 ArrayList,默认容量为 10
    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list);
}
1.2 带有初始容量的构造方法

如果预估数据量较大,建议直接指定初始容量,避免频繁扩容导致的内存拷贝开销。

// 创建一个有初始容量的 ArrayList
ArrayList<Integer> list2 = new ArrayList<>(5);
list2.add(22);
list2.add(33);
list2.add(44);
System.out.println(list2);
1.3 用其他集合类构造 ArrayList

传入的参数必须是实现了 Collection 接口的对象,且类型需兼容。

// 从另一个 ArrayList 初始化
ArrayList<Integer> list3 = new ArrayList<>(list2);

2. 操作方法

方法签名描述
boolean add(E e)将元素 e 插入到列表末尾
void add(int index, E element)将元素插入到指定的 index 位置
boolean addAll(Collection<? extends E> c)将集合 c 中的所有元素插入到列表末尾
E remove(int index)删除并返回指定 index 位置的元素
boolean remove(Object o)删除列表中第一个遇到的元素 o
E get(int index)获取指定 index 位置的元素
E set(int index, E element)将指定 index 位置的元素替换为 element
void clear()清空列表中的所有元素
List<E> subList(int fromIndex, int toIndex)返回从 fromIndex 到 toIndex 的子列表
2.1 添加操作

尾插是最常用的操作,时间复杂度接近 O(1)。如果在中间插入,需要移动后续元素,复杂度为 O(n)。

// 尾插
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
System.out.println(list);

// 指定位置插入
list.add(0, 1);
System.out.println(list);
2.2 批量添加与移除

addAll 可以一次性导入多个元素,remove 既支持下标也支持对象引用。

// 批量添加
ArrayList<Integer> list2 = new ArrayList<>();
list2.addAll(list);
list2.add(1111);
System.out.println(list2);

// 移除元素
list.remove(2); // 按索引
Integer x = 2;
list.remove(x); // 按对象
2.3 子列表截取

subList 返回的是原列表的视图,修改子列表会影响原列表,因为它们是共享地址的。注意截取范围是左闭右开。

ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(11);
list.add(111);
list.add(1111);

List<Integer> subList = list.subList(1, 3);
System.out.println(subList); // 输出 [11, 111]

具体方法的底层实现逻辑较为复杂,涉及数组拷贝和边界检查,实际开发中直接调用即可,遇到并发问题需注意同步。

三、ArrayList 的遍历

遍历方式的选择取决于具体场景,比如是否需要修改元素或倒序访问。

1. for 循环遍历

适用于已知索引范围,性能较好。

for (int i = 0; i < list.size(); i++) {
    Integer a = list.get(i);
    System.out.println(a + " ");
}

2. 增强型 for 循环

语法简洁,但内部使用迭代器,不支持快速失败检测外的修改操作。

for (Integer x : list) {
    System.out.println(x + " ");
}

3. 迭代器

提供了更灵活的控制,如从指定位置开始、逆向遍历等。

// 正向遍历
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next() + " ");
}

// 从指定位置开始
ListIterator<Integer> it2 = list.listIterator(2);
while (it2.hasNext()) {
    System.out.println(it2.next() + " ");
}

// 逆向打印
ListIterator<Integer> it = list.listIterator(list.size());
while (it.hasPrevious()) {
    System.out.println(it.previous() + " ");
}

四、ArrayList 扩容机制

ArrayList 是一个动态类型的顺序表,在插入元素的过程中会自动扩容。这是其'动态'特性的核心体现。

如果调用不带参数的构造方法,第一次分配数组大小为 10,后续扩容为 1.5 倍。

当元素数量超过当前容量时,会触发扩容逻辑。新容量通常是旧容量的 1.5 倍加 1(具体计算涉及位运算优化)。扩容过程涉及创建新数组和复制旧数据,因此频繁扩容会影响性能,这也是为什么推荐在初始化时预估容量。

扩容机制流程

总结

ArrayList 是基于动态数组的 List 实现,具有随机访问快、使用便捷的特点。理解其底层结构和扩容机制,有助于在实际开发中做出更优的性能决策。在单线程环境下它是首选,但在高并发场景中务必考虑线程安全问题。

目录

  1. Java ArrayList 核心解析
  2. 一、ArrayList 的概念
  3. 二、ArrayList 的使用
  4. 1. 构造 ArrayList
  5. 1.1 无参构造方法
  6. 1.2 带有初始容量的构造方法
  7. 1.3 用其他集合类构造 ArrayList
  8. 2. 操作方法
  9. 2.1 添加操作
  10. 2.2 批量添加与移除
  11. 2.3 子列表截取
  12. 三、ArrayList 的遍历
  13. 1. for 循环遍历
  14. 2. 增强型 for 循环
  15. 3. 迭代器
  16. 四、ArrayList 扩容机制
  17. 总结

更多推荐文章

查看全部
  • Web3 前端安全:钱包连接风险与防护指南
  • 手势控制电脑方案分析与 Python 实现示例
  • 数据结构 - 多维数组的超平面视角:从索引到地址的映射
  • Java 企业电子招投标采购系统功能模块与数字化管理
  • OpenClaw Gateway 服务运维:启动、停止与监控
  • Lua 语言入门指南
  • 基于 Docker 在 NVIDIA 5090 上部署 ComfyUI 与 Stable-Diffusion-Webui
  • 理解 RAG 真实边界:Spring AI 三种架构落地实践
  • DeepSeek-R1-Distill-Llama-8B 模型安全与对抗攻击防护
  • C++ 内存管理进阶:从裸指针到智能指针的实战指南
  • C++11 新特性详解:Lambda、移动语义与可变参数模板
  • HarmonyOS6 RcButton 组件样式系统深度剖析
  • 2026 春晚国产人形机器人技术突破与核心架构解析
  • 医疗连续体机器人模块化控制界面设计与 Python 库应用
  • 二级 Python 考试真题及参考代码解析(基本操作篇)
  • OpenCLAW 在 CentOS 7 环境下的安装部署
  • Visual C++ 运行库全版本一键安装工具 VisualCppRedist AIO 使用指南
  • 相交链表题解与详细分析
  • 在 Kubernetes 中部署 Kafka 高可用集群实战
  • 飞算 JavaAI:智能编程助手助力 Java 高效开发

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online