什么是 ArrayList?
ArrayList 是一个动态数组的实现,它位于 java.util 包下,实现了 List 接口,相比于 Java 中固定长度的数组,ArrayList 的最大优势在于其大小可变,可以根据需要自动扩容。

核心特点:
- 动态大小:可以随时添加或删除元素,而无需关心其容量。
- 有序性:元素按照插入的顺序存储,并可以通过索引(0-based)访问。
- 允许重复元素:可以存储多个
null值。 - 非线程安全:在多线程环境下,如果多个线程同时修改一个
ArrayList,可能会导致数据不一致,如果需要线程安全,可以使用Vector或Collections.synchronizedList()包装的ArrayList。
如何创建 ArrayList?
主要有三种方式来创建 ArrayList 对象。
创建一个空的 ArrayList
这种方式最常用,创建一个可以存储 String 类型元素的列表。
import java.util.ArrayList; import java.util.List; // 使用泛型 <String> 来指定列表中只能存储 String 类型的对象 List<String> stringList = new ArrayList<>();
创建一个指定初始容量的 ArrayList
如果你预先知道列表大概要存储多少个元素,可以指定初始容量以减少扩容操作,提高性能。

// 创建一个初始容量为 10 的 ArrayList List<String> stringListWithCapacity = new ArrayList<>(10);
使用另一个集合来初始化 ArrayList
你可以用已有的 List, Set 或其他集合来创建一个新的 ArrayList。
List<String> existingList = new ArrayList<>();
existingList.add("Apple");
existingList.add("Banana");
// 使用 existingList 初始化一个新的 ArrayList
List<String> newList = new ArrayList<>(existingList);
System.out.println(newList); // 输出: [Apple, Banana]
常用方法详解
下面是 ArrayList 最核心的一些方法,并附有示例代码。
1 添加元素
| 方法 | 描述 | 示例 |
|---|---|---|
add(E e) |
在列表的末尾添加一个元素。 | list.add("Cat"); |
add(int index, E e) |
在列表的指定 index 位置插入一个元素。 |
list.add(1, "Dog"); |
List<String> animals = new ArrayList<>();
// 1. add(E e) - 在末尾添加
animals.add("Lion");
animals.add("Tiger");
System.out.println("添加后: " + animals); // 输出: [Lion, Tiger]
// 2. add(int index, E e) - 在指定位置插入
animals.add(1, "Elephant"); // 在索引 1 的位置插入 "Elephant"
System.out.println("插入后: " + animals); // 输出: [Lion, Elephant, Tiger]
2 获取元素
| 方法 | 描述 | 示例 |
|---|---|---|
get(int index) |
返回列表中指定 index 位置的元素。 |
String name = list.get(0); |
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
// get(int index)
String firstFruit = fruits.get(0); // 获取索引为 0 的元素
System.out.println("第一个水果是: " + firstFruit); // 输出: 第一个水果是: Apple
3 修改元素
| 方法 | 描述 | 示例 |
|---|---|---|
set(int index, E e) |
用指定的元素替换列表中指定 index 位置的元素。 |
list.set(0, "New Apple"); |
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
System.out.println("修改前: " + fruits); // 输出: [Apple, Banana]
// set(int index, E e)
fruits.set(1, "Orange"); // 将索引 1 的 "Banana" 替换为 "Orange"
System.out.println("修改后: " + fruits); // 输出: [Apple, Orange]
4 删除元素
| 方法 | 描述 | 示例 |
|---|---|---|
remove(int index) |
移除列表中指定 index 位置的元素,并返回被移除的元素。 |
list.remove(0); |
remove(Object o) |
移除列表中第一个出现的指定元素 o,如果元素存在,返回 true,否则返回 false。 |
list.remove("Apple"); |
List<String> pets = new ArrayList<>();
pets.add("Dog");
pets.add("Cat");
pets.add("Parrot");
pets.add("Cat"); // 添加一个重复的 "Cat"
System.out.println("删除前: " + pets); // 输出: [Dog, Cat, Parrot, Cat]
// remove(int index)
String removedPet = pets.remove(0); // 删除索引为 0 的 "Dog"
System.out.println("被删除的宠物是: " + removedPet); // 输出: 被删除的宠物是: Dog
System.out.println("删除索引0后: " + pets); // 输出: [Cat, Parrot, Cat]
// remove(Object o)
boolean isRemoved = pets.remove("Cat"); // 删除第一个出现的 "Cat"
System.out.println("是否成功删除 'Cat': " + isRemoved); // 输出: true
System.out.println("删除元素后: " + pets); // 输出: [Parrot, Cat]
5 查询与判断
| 方法 | 描述 | 示例 |
|---|---|---|
size() |
返回列表中的元素个数(不是容量)。 | int count = list.size(); |
isEmpty() |
如果列表不包含元素,则返回 true。 |
boolean empty = list.isEmpty(); |
contains(Object o) |
如果列表中包含指定的元素,则返回 true。 |
boolean hasCat = list.contains("Cat"); |
indexOf(Object o) |
返回此列表中第一次出现的指定元素的索引;如果列表不包含该元素,则返回 -1。 | int index = list.indexOf("Cat"); |
lastIndexOf(Object o) |
返回此列表中最后一次出现的指定元素的索引。 | int lastIndex = list.lastIndexOf("Cat"); |
List<String> colors = new ArrayList<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");
colors.add("Green");
System.out.println("颜色列表: " + colors);
// size()
System.out.println("列表大小: " + colors.size()); // 输出: 4
// isEmpty()
System.out.println("列表是否为空: " + colors.isEmpty()); // 输出: false
// contains(Object o)
System.out.println("列表是否包含 'Green': " + colors.contains("Green")); // 输出: true
// indexOf(Object o)
System.out.println("'Green' 第一次出现的索引: " + colors.indexOf("Green")); // 输出: 1
// lastIndexOf(Object o)
System.out.println("'Green' 最后一次出现的索引: " + colors.lastIndexOf("Green")); // 输出: 3
6 遍历 ArrayList
有四种主要的方式遍历 ArrayList。
for 循环(通过索引) 最传统的方式,适合需要通过索引操作元素的场景。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (int i = 0; i < names.size(); i++) {
System.out.println("索引 " + i + ": " + names.get(i));
}
for-each 循环(增强 for 循环) 最简洁、最推荐的方式,适用于只需要读取每个元素的场景。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println("名字: " + name);
}
使用 Iterator(迭代器)
可以在遍历时安全地删除元素,避免 ConcurrentModificationException。
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if ("Bob".equals(name)) {
iterator.remove(); // 使用迭代器的 remove 方法安全删除
}
}
System.out.println("删除 Bob 后: " + names); // 输出: [Alice, Charlie]
使用 Java 8+ 的 Stream API 功能最强大,可以进行链式操作,如过滤、排序、映射等。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 1. 简单遍历
names.stream().forEach(name -> System.out.println("Stream 遍历: " + name));
// 2. 过滤并打印长度大于 4 的名字
System.out.println("\n名字长度大于 4 的:");
names.stream()
.filter(name -> name.length() > 4)
.forEach(System.out::println);
// 输出:
// 名字长度大于 4 的:
// Alice
// Charlie
// David
7 其他重要方法
| 方法 | 描述 | 示例 |
|---|---|---|
clear() |
移除列表中的所有元素。 | list.clear(); |
toArray() |
将列表转换为一个数组。 | Object[] array = list.toArray(); |
List<String> temp = new ArrayList<>();
temp.add("One");
temp.add("Two");
System.out.println("清空前: " + temp); // 输出: [One, Two]
temp.clear();
System.out.println("清空后: " + temp); // 输出: []
System.out.println("列表是否为空: " + temp.isEmpty()); // 输出: true
// toArray()
List<String> numbers = Arrays.asList("1", "2", "3");
String[] stringArray = numbers.toArray(new String[0]);
System.out.println("转换后的数组: " + Arrays.toString(stringArray)); // 输出: [1, 2, 3]
ArrayList vs. 固定数组
| 特性 | ArrayList |
固定数组 (String[]) |
|---|---|---|
| 大小 | 动态可变 | 固定不变 |
| 性能 | 添加元素可能触发扩容,有性能开销,随机访问(get)性能高,接近 O(1)。 |
创建后大小固定,没有扩容开销,随机访问性能高,O(1)。 |
| 功能 | 提供丰富的 API,如 add, remove, size, contains 等。 |
功能有限,需要自己实现或借助工具类。 |
| 使用场景 | 绝大多数情况,特别是元素数量不确定或需要频繁增删的场景。 | 元素数量确定且不变的场景,或者对性能要求极高的底层代码。 |
最佳实践与注意事项
- 始终使用泛型:像
List<String>而不是List,这样可以确保类型安全,避免在运行时出现ClassCastException。 - 避免在循环中删除元素:如果你想在遍历
ArrayList时删除多个元素,不要使用for循环和list.remove(index)的组合,因为这会导致索引错乱,推荐使用 Iterator 的remove()方法。 - 初始化容量:如果你能预估
ArrayList的大致大小,在创建时指定一个合理的初始容量(如new ArrayList<>(1000)),可以避免多次扩容,提高性能。 - 理解
size()和capacity:size()是当前元素的个数,而capacity是底层数组的长度。ArrayList在size超过capacity时会自动扩容(通常是扩容为原来的 1.5 倍)。 - 线程安全:
ArrayList不是线程安全的,如果在多线程环境下共享一个ArrayList实例,必须进行同步处理,简单的方法是使用Collections.synchronizedList(new ArrayList<>())。
// 线程安全的 ArrayList List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
完整示例代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
// 1. 创建 ArrayList
List<String> fruits = new ArrayList<>();
System.out.println("初始列表: " + fruits);
// 2. 添加元素
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
System.out.println("添加后: " + fruits);
// 3. 在指定位置插入
fruits.add(1, "Blueberry");
System.out.println("插入后: " + fruits);
// 4. 获取元素
String firstFruit = fruits.get(0);
System.out.println("第一个水果: " + firstFruit);
// 5. 修改元素
fruits.set(2, "Blackberry");
System.out.println("修改后: " + fruits);
// 6. 查询
System.out.println("列表大小: " + fruits.size());
System.out.println("是否包含 'Apple': " + fruits.contains("Apple"));
System.out.println("'Banana' 的索引: " + fruits.indexOf("Banana"));
// 7. 删除元素
fruits.remove("Blueberry"); // 删除特定元素
System.out.println("删除 'Blueberry' 后: " + fruits);
String removedFruit = fruits.remove(0); // 删除指定索引的元素
System.out.println("被删除的元素: " + removedFruit);
System.out.println("删除索引0后: " + fruits);
// 8. 遍历 ArrayList
System.out.println("\n--- 遍历方式 ---");
// a. for-each 循环 (推荐)
System.out.println("使用 for-each:");
for (String fruit : fruits) {
System.out.println(fruit);
}
// b. 使用 Iterator (安全删除)
System.out.println("\n使用 Iterator 删除 'Cherry':");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
if ("Cherry".equals(fruit)) {
iterator.remove();
}
}
System.out.println("删除后: " + fruits);
// 9. 清空列表
fruits.clear();
System.out.println("\n清空后列表: " + fruits);
System.out.println("列表是否为空: " + fruits.isEmpty());
}
}
希望这份详细的指南能帮助你全面掌握 Java ArrayList 的用法!
