什么是 ArrayList?
ArrayList 是 Java 集合框架中一个最常用的类,它是一个动态数组,意味着你可以在运行时动态地添加或删除元素,而不需要像普通数组那样在创建时就指定固定的大小。

核心特点:
- 有序性: 元素的存储和取出顺序是一致的(基于插入顺序)。
- 可重复性: 允许存储重复的元素。
- 动态扩容: 当元素数量超过其当前容量时,
ArrayList会自动扩容(通常是扩容为原来的1.5倍)。 - 非线程安全: 在多线程环境下,如果多个线程同时修改一个
ArrayList,可能会导致数据不一致,如果需要线程安全,应该使用Vector或CopyOnWriteArrayList。 - 性能:
- 随机访问快: 因为底层是数组,所以通过索引(
get(int index))访问元素的速度非常快,时间复杂度为 O(1)。 - 增删慢: 在中间或头部添加/删除元素时,需要移动大量元素,时间复杂度为 O(n)。
- 随机访问快: 因为底层是数组,所以通过索引(
如何定义(声明和初始化)ArrayList
定义 ArrayList 通常需要两步:声明 和 初始化。
1 基本语法
最推荐的、也是最现代的方式是使用 钻石操作符 <>(Java 7 引入),它可以让编译器自动推断泛型类型。
// 声明一个 ArrayList 变量 // <E> 中的 E 代表 Element(元素),你需要指定要存储的元素类型 ArrayList<E> listName; // 初始化这个 ArrayList listName = new ArrayList<>();
示例:

// 1. 声明一个可以存储 String 类型元素的 ArrayList ArrayList<String> stringList; // 2. 初始化这个 ArrayList stringList = new ArrayList<>(); // 也可以在一行中完成声明和初始化 ArrayList<Integer> numberList = new ArrayList<>();
2 E 的含义:泛型
<E> 是 Java 的泛型 语法,它强制 ArrayList 只能存储特定类型的对象,保证了类型安全,避免了在运行时进行类型转换的麻烦和风险。
ArrayList<String>:只能存储String对象。ArrayList<Integer>:只能存储Integer对象(注意:基本类型int不能直接使用,必须使用其包装类Integer)。ArrayList<Double>:只能存储Double对象。ArrayList<MyCustomClass>:只能存储MyCustomClass的实例。
完整示例:定义、添加、访问、修改、删除
下面是一个完整的示例,展示了 ArrayList 的生命周期。
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
// 1. 定义并初始化一个存储 String 的 ArrayList
ArrayList<String> fruits = new ArrayList<>();
// 2. 添加元素
// 使用 add() 方法在列表末尾添加元素
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
System.out.println("初始列表: " + fruits); // 输出: [Apple, Banana, Orange]
// 3. 在指定位置插入元素
fruits.add(1, "Mango"); // 在索引 1 的位置插入 "Mango"
System.out.println("插入 Mango 后: " + fruits); // 输出: [Apple, Mango, Banana, Orange]
// 4. 访问元素
// 使用 get(int index) 方法通过索引获取元素
String firstFruit = fruits.get(0);
System.out.println("第一个水果是: " + firstFruit); // 输出: Apple
// 5. 修改元素
// 使用 set(int index, E element) 方法修改指定索引的元素
fruits.set(2, "Pineapple"); // 将索引 2 的 "Banana" 改为 "Pineapple"
System.out.println("修改后: " + fruits); // 输出: [Apple, Mango, Pineapple, Orange]
// 6. 删除元素
// 使用 remove(int index) 方法删除指定索引的元素
fruits.remove(1); // 删除索引 1 的 "Mango"
System.out.println("删除索引 1 的元素后: " + fruits); // 输出: [Apple, Pineapple, Orange]
// 使用 remove(Object o) 方法删除第一个匹配的元素
fruits.remove("Orange");
System.out.println("删除 Orange 后: " + fruits); // 输出: [Apple, Pineapple]
// 7. 获取列表大小
System.out.println("列表中水果的数量: " + fruits.size()); // 输出: 2
// 8. 检查列表是否为空
System.out.println("列表是否为空? " + fruits.isEmpty()); // 输出: false
// 9. 遍历列表
System.out.println("--- 遍历列表 ---");
for (int i = 0; i < fruits.size(); i++) {
System.out.println("索引 " + i + ": " + fruits.get(i));
}
// 使用 for-each 循环 (更简洁)
System.out.println("--- 使用 for-each 遍历 ---");
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}
其他重要的定义和初始化方式
1 指定初始容量
如果你预先知道 ArrayList 大概会存储多少个元素,可以在初始化时指定一个初始容量,这可以避免在添加元素过程中因多次扩容而带来的性能开销。
// 初始容量为 10 ArrayList<String> names = new ArrayList<>(10);
2 使用另一个集合初始化
你可以使用一个已有的 Collection(如另一个 ArrayList 或 LinkedList)来初始化一个新的 ArrayList,新列表将包含原始集合中的所有元素。

ArrayList<String> list1 = new ArrayList<>();
list1.add("A");
list1.add("B");
list1.add("C");
// 使用 list1 来初始化 list2
ArrayList<String> list2 = new ArrayList<>(list1);
System.out.println(list2); // 输出: [A, B, C]
3 使用 Java 8 的 Arrays.asList()
这是一种非常方便的创建不可变列表的方式,它返回的是一个固定大小的列表,你不能添加或删除元素,但可以修改现有元素的值。
import java.util.Arrays;
import java.util.List; // 注意,这里导入的是 java.util.List
// 定义并初始化一个包含固定元素的 List
List<String> colors = Arrays.asList("Red", "Green", "Blue");
System.out.println(colors); // 输出: [Red, Green, Blue]
// colors.add("Yellow"); // 这行代码会抛出 UnsupportedOperationException 异常
// colors.remove(0); // 这行代码也会抛出 UnsupportedOperationException 异常
// 但是可以修改
colors.set(0, "Purple");
System.out.println(colors); // 输出: [Purple, Green, Blue]
4 使用 Java 9+ 的 List.of()
这是 Java 9 引入的创建不可变列表的更现代、更简洁的方法,它与 Arrays.asList() 类似,但返回的列表是完全不可变的,既不能修改、添加也不能删除元素。
import java.util.List; // 导入 java.util.List // 定义并初始化一个不可变的 List List<Integer> numbers = List.of(1, 2, 3, 4, 5); System.out.println(numbers); // 输出: [1, 2, 3, 4, 5] // numbers.add(6); // 抛出 UnsupportedOperationException // numbers.set(0, 10); // 抛出 UnsupportedOperationException // numbers.remove(0); // 抛出 UnsupportedOperationException
ArrayList vs. 数组 ([])
| 特性 | ArrayList |
数组 (int[], String[]) |
|---|---|---|
| 大小 | 动态,可自动扩容 | 固定,创建时必须指定大小 |
| 性能 | 随机访问快,增删慢 | 随机访问快,增删慢(需要创建新数组) |
| 类型 | 使用泛型,只能存储对象 | 可以存储基本类型(如 int, char)和对象 |
| 功能 | 提供丰富的方法(add, remove, size 等) |
功能有限,长度固定 |
| 使用场景 | 当元素数量不确定或需要频繁增删时 | 当元素数量固定、性能要求极高且需要存储基本类型时 |
- 定义
ArrayList的标准方式:ArrayList<Type> listName = new ArrayList<>(); - 务必使用泛型 (
<Type>) 来指定要存储的元素类型,以保证类型安全。 ArrayList是一个功能强大的动态数组,适合大多数需要存储和操作对象集合的场景。- 根据你的具体需求(是否需要修改、初始大小是否已知等),可以选择不同的初始化方式。
