Java ArrayList 动态数组核心原理与使用指南
Java ArrayList 是基于动态数组实现的 List 接口常用类,支持随机访问和序列化。其构造方法、核心操作方法(增删改查)、遍历方式以及底层扩容机制。ArrayList 默认初始容量为 10,扩容时按 1.5 倍增长,非线程安全,适用于单线程读多写少场景。

Java ArrayList 是基于动态数组实现的 List 接口常用类,支持随机访问和序列化。其构造方法、核心操作方法(增删改查)、遍历方式以及底层扩容机制。ArrayList 默认初始容量为 10,扩容时按 1.5 倍增长,非线程安全,适用于单线程读多写少场景。

ArrayList是 Java 集合框架(Java Collections Framework)中最常用的动态数组实现,它提供了灵活的容量管理、便捷的增删改查操作,广泛应用于日常开发中。本文将深入剖析 ArrayList 的底层结构、核心方法源码、性能特点及最佳实践,帮助读者彻底掌握这一基础数据结构。
ArrayList 基于动态数组实现,底层维护一个 Object[] 数组,elementData 存储元素,同时通过 size 变量记录当前有效元素个数,容量可自动扩容。它实现了 List 接口,如下图:

ArrayList 是以泛型方式实现,使用时必须实例化;ArrayList 实现 RandomAccess 接口,ArrayList 可随机访问;ArrayList 实现 Cloneable 接口,ArrayList 可以克隆;ArrayList 实现 Serializable 接口,支持序列化;ArrayList 不是线程安全,在单线程下可以使用,在多线程中可以选择 Vector 或者 CopyOnWriteArrayList;ArrayList 底层是一段连续的空间,可以自动扩容,是一个动态类型的顺序表。
ArrayList 提供三种构造函数:
| 方法 | 说明 |
|---|---|
ArrayList() | 无参构造 |
ArrayList(Collection<? extends E> c) | 利用其他 Collection 构建 ArrayList |
ArrayList(int initialCapacity) | 指定顺序表初始容量 |
public static void main(String[] args) {
// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
}
【源码:】

// 创建一个有初始容量的 ArrayList
ArrayList<Integer> list2 = new ArrayList<>(5);
list2.add(22);
list2.add(33);
list2.add(44);
System.out.println(list2);
【源码:】

类型一定是实现了 Collection 接口,传的参数要是 E 或 E 的子类。
// 创建一个有初始容量的 ArrayList
ArrayList<Integer> list2 = new ArrayList<>(5);
list2.add(22);
list2.add(33);
list2.add(44);
System.out.println(list2);
// 都是 Integer 类型,可以传 ArrayList<Integer>
ArrayList<Integer> list3 = new ArrayList<>(list2);
【源码:】

| 方法签名 | 描述 |
|---|---|
boolean add(E e) | 将元素 e 插入到列表末尾 |
void add(int index, E element) | 将元素 e 插入到指定的 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() | 清空列表中的所有元素 |
boolean contains(Object o) | 判断列表中是否包含元素 o |
int indexOf(Object o) | 返回第一个匹配元素 o 的索引 |
int lastIndexOf(Object o) | 返回最后一个匹配元素 o 的索引 |
List<E> subList(int fromIndex, int toIndex) | 返回从 fromIndex 到 toIndex 的子列表 |
// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
// 末尾插入 1
list.add(1);
System.out.println(list);
// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
// 0 位置插入 1
list.add(0, 1);
System.out.println(list);
// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
// 0 位置插入 1
list.add(1);
list.add(11);
list.add(111);
System.out.println(list);
ArrayList<Integer> list2 = new ArrayList<>();
list2.addAll(list);
list2.add(1111);
System.out.println(list2);

// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
// 0 位置插入 1
list.add(1);
list.add(11);
list.add(111);
System.out.println(list);
list.remove(2); // 下标
// 对象
list.remove(new Integer(2));
Integer x = 2;
// 写法 2
list.remove(x);
// 创建一个空的 ArrayList
ArrayList<Integer> list = new ArrayList<>();
// 0 位置插入 1
list.add(1);
list.add(11);
list.add(111);
list.add(1111);
System.out.println(list);
List<Integer> subList = list.subList(1, 3);
System.out.println(subList);
它的截取是左闭右开,截取 1~3 位置,取 2,3 后面如果修改元素,截取的也会随之修改,实际截取的是地址。

一些简单的方法就不一一列举了,直接调用就行,具体的方法实现可以参考官方文档。
for (int i = 0; i < list.size(); i++) {
Integer a = list.get(i);
System.out.println(a + " ");
}
for (int x : list) {
System.out.println(x + " ");
}
只要实现 Iterable 接口,都可以使用迭代器打印。
it.next(): 访问下一个,it 望后走一步。
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 是一个动态类型的顺序表,在插入元素的过程中会自动扩容。
如果调用不带参数的构造方法,第一次分配数组大小为 10,后续扩容为 1.5 倍扩容。
源码如下:



【总结】
ArrayList 是基于动态数组的 List 实现,具有随机访问快、使用便捷的特点,适合大多数读多写少的场景。本文从底层原理、核心方法、性能分析到注意事项,全面剖析了 ArrayList 的特性,希望能帮助读者深入理解并灵活运用这一基础数据结构。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online