一、创建和初始化
1. 创建 ArrayList
java
复制代码
// 1. 默认初始容量10
ArrayList<String> list1 = new ArrayList<>();
// 2. 指定初始容量
ArrayList<String> list2 = new ArrayList<>(50);
// 3. 从其他集合创建
List<String> existingList = Arrays.asList("A", "B", "C");
ArrayList<String> list3 = new ArrayList<>(existingList);
// 4. Java 10+ 使用 var
var list4 = new ArrayList<Integer>();
// 5. 使用 Collections 工具类
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
2. 快速初始化
java
复制代码
// Java 9+ 工厂方法(返回的是不可变List)
List<String> fixedList = List.of("A", "B", "C");
// 如果需要可变的ArrayList
ArrayList<String> mutableList = new ArrayList<>(List.of("A", "B", "C"));
// 传统方式
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "A", "B", "C");
二、添加元素
1. 基本添加操作
java
复制代码
ArrayList<String> list = new ArrayList<>();
// 1. 添加到末尾
list.add("Apple"); // ["Apple"]
list.add("Banana"); // ["Apple", "Banana"]
boolean added = list.add("Cherry"); // true, ["Apple", "Banana", "Cherry"]
// 2. 添加到指定位置
list.add(1, "Orange"); // ["Apple", "Orange", "Banana", "Cherry"]
// 3. 添加多个元素
list.addAll(List.of("Grape", "Mango")); // ["Apple", "Orange", "Banana", "Cherry", "Grape", "Mango"]
list.addAll(2, List.of("Pear", "Peach")); // 从指定位置添加
三、访问和修改元素
1. 获取元素
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
// 1. 获取指定位置
String first = list.get(0); // "A"
// 2. 获取第一个和最后一个
String first2 = list.getFirst(); // Java 21+ "A"
String last = list.getLast(); // Java 21+ "D"
// 3. 获取子列表(视图,共享底层数组)
List<String> subList = list.subList(1, 3); // ["B", "C"](不包括索引3)
2. 修改元素
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C"));
// 修改指定位置元素
String old = list.set(1, "BB"); // 返回旧值:"B",列表变为["A", "BB", "C"]
四、删除元素
1. 按索引删除
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
// 删除指定位置
String removed = list.remove(1); // 返回被删除的"B",列表变为["A", "C", "D"]
2. 按元素删除
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C", "B"));
// 删除第一次出现的元素
boolean removed = list.remove("B"); // true,列表变为["A", "C", "B"]
// 删除所有匹配元素(Java 8+)
list.removeIf(s -> s.startsWith("A")); // 删除所有以"A"开头的元素
// 删除多个元素
list.removeAll(List.of("B", "C")); // 删除所有"B"和"C"
list.retainAll(List.of("A", "D")); // 只保留"A"和"D",删除其他
3. 清空列表
java
复制代码
list.clear(); // 清空所有元素
五、查找和判断
1. 查找元素
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C", "B", "A"));
// 1. 判断包含
boolean hasA = list.contains("A"); // true
boolean hasAll = list.containsAll(List.of("A", "B")); // true
// 2. 查找索引
int firstIndex = list.indexOf("B"); // 1(第一次出现)
int lastIndex = list.lastIndexOf("B"); // 3(最后一次出现)
int notFound = list.indexOf("X"); // -1(未找到)
2. 列表信息
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C"));
int size = list.size(); // 3
boolean empty = list.isEmpty(); // false
六、遍历和迭代
1. 不同遍历方式
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C"));
// 1. for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 2. 增强for循环
for (String item : list) {
System.out.println(item);
}
// 3. 迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
if ("B".equals(item)) {
iterator.remove(); // 安全删除
}
}
// 4. ListIterator(双向遍历)
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
// 5. Java 8+ forEach
list.forEach(item -> System.out.println(item));
list.forEach(System.out::println);
2. 并行遍历
java
复制代码
// 并行流遍历(Java 8+)
list.parallelStream().forEach(item -> {
System.out.println(Thread.currentThread().getName() + ": " + item);
});
七、转换和操作
1. 转换为数组
java
复制代码
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C"));
// 1. 转换为Object数组
Object[] array1 = list.toArray(); // Object[]
// 2. 转换为指定类型数组
String[] array2 = list.toArray(new String[0]); // String[]
String[] array3 = list.toArray(String[]::new); // Java 11+ 方法引用
2. 排序和反转
java
复制代码
ArrayList<Integer> numbers = new ArrayList<>(List.of(3, 1, 4, 1, 5));
// 1. 自然排序
Collections.sort(numbers); // [1, 1, 3, 4, 5]
// 2. 自定义排序
numbers.sort(Comparator.reverseOrder()); // [5, 4, 3, 1, 1]
// 3. 反转
Collections.reverse(numbers); // [1, 1, 3, 4, 5] -> [5, 4, 3, 1, 1]
// 4. 打乱顺序
Collections.shuffle(numbers); // 随机打乱
八、Stream API 操作(Java 8+)
java
复制代码
ArrayList<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5));
// 1. 过滤
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList()); // [2, 4]
// 2. 映射
List<String> strings = numbers.stream()
.map(n -> "Number: " + n)
.collect(Collectors.toList());
// 3. 统计
long count = numbers.stream().count(); // 5
int sum = numbers.stream().mapToInt(Integer::intValue).sum(); // 15
Optional<Integer> max = numbers.stream().max(Integer::compare);
// 4. 分组
Map<Boolean, List<Integer>> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(n -> n > 3));
// {false=[1,2,3], true=[4,5]}
九、容量和性能
1. 容量管理
java
复制代码
ArrayList<String> list = new ArrayList<>();
// 确保最小容量
list.ensureCapacity(100); // 提前分配空间,避免多次扩容
// 缩减容量到实际大小
list.trimToSize(); // 释放多余空间
2. 性能提示
java
复制代码
// 1. 预分配容量(避免频繁扩容)
ArrayList<String> list = new ArrayList<>(1000);
// 2. 批量操作 vs 单个操作
// ❌ 低效(多次扩容)
for (int i = 0; i < 1000; i++) {
list.add("item" + i);
}
// ✅ 高效
list.addAll(Collections.nCopies(1000, "item"));
// 3. 使用合适的遍历方式
// 随机访问用 for-i 循环
for (int i = 0; i < list.size(); i++) {
list.get(i); // O(1) 时间复杂度
}
十、线程安全处理
1. 同步包装
java
复制代码
// 创建线程安全的ArrayList
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 使用时需要手动同步
synchronized(syncList) {
syncList.add("item");
// 遍历也需要同步
for (String item : syncList) {
System.out.println(item);
}
}
2. CopyOnWriteArrayList(读多写少场景)
java
复制代码
import java.util.concurrent.CopyOnWriteArrayList;
CopyOnWriteArrayList<String> safeList = new CopyOnWriteArrayList<>();
safeList.add("item"); // 线程安全,每次写操作复制底层数组
十一、实际应用示例
java
复制代码
public class ArrayListExample {
public static void main(String[] args) {
// 1. 学生成绩管理
ArrayList<Integer> scores = new ArrayList<>();
scores.add(85);
scores.add(92);
scores.add(78);
// 计算平均分
double average = scores.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
// 2. 购物车实现
class ShoppingCart {
private ArrayList<String> items = new ArrayList<>();
public void addItem(String item) {
items.add(item);
}
public void removeItem(String item) {
items.remove(item);
}
public List<String> getItems() {
return new ArrayList<>(items); // 返回副本
}
}
// 3. 数据过滤和转换
ArrayList<String> rawData = new ArrayList<>(
List.of("apple", "banana", "cherry", "date", "elderberry")
);
// 过滤长度大于5的字符串并转换为大写
List<String> processed = rawData.stream()
.filter(s -> s.length() > 5)
.map(String::toUpperCase)
.collect(Collectors.toList());
// ["ELDERBERRY"]
}
}
十二、常见问题及解决
1. ConcurrentModificationException
java
复制代码
// ❌ 错误:遍历时修改列表
ArrayList<String> list = new ArrayList<>(List.of("A", "B", "C"));
for (String item : list) {
if ("B".equals(item)) {
list.remove(item); // 抛出异常!
}
}
// ✅ 正确1:使用迭代器删除
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if ("B".equals(it.next())) {
it.remove(); // 安全删除
}
}
// ✅ 正确2:Java 8+ removeIf
list.removeIf(item -> "B".equals(item));
2. 空值处理
java
复制代码
ArrayList<String> list = new ArrayList<>();
list.add(null); // ArrayList允许null值
// 检查时注意
if (list.contains(null)) {
System.out.println("列表包含null");
}
总结要点
- 动态数组:自动扩容,初始容量10,每次扩容1.5倍
- 随机访问 :
get(index) 是 O(1) 时间复杂度
- 非线程安全:多线程环境需要外部同步
- 允许null:可以存储null元素
- 快速失败:迭代器是快速失败的
- 性能优化:预分配容量,批量操作
- 现代用法:结合Stream API进行函数式操作