Java集合遍历
外观
Java集合遍历[编辑 | 编辑源代码]
Java集合遍历是指按特定顺序访问Java集合框架中元素的过程。作为数据处理的核心操作,遍历方式的选择直接影响代码的性能和可读性。本章将系统讲解5种主流遍历方法及其最佳实践。
核心概念[编辑 | 编辑源代码]
Java集合框架提供了三种主要的遍历范式:
- 显式迭代器模式:通过或
Iterator
实现ListIterator
- 隐式迭代语法:增强for循环(for-each)语法糖
- 函数式遍历:Java 8引入的Stream API
遍历方法详解[编辑 | 编辑源代码]
1. 迭代器(Iterator)[编辑 | 编辑源代码]
最基础的遍历方式,适用于所有
Collection
实现类:
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// 安全删除当前元素
if (fruit.startsWith("A")) {
iterator.remove();
}
}
输出:
Apple Banana Cherry
页面模块:Message box/ambox.css没有内容。
直接调用集合的 remove()
remove()
ConcurrentModificationException
|
2. 增强for循环[编辑 | 编辑源代码]
语法最简洁的遍历方式,编译后实际转换为迭代器模式:
Set<Integer> primes = new HashSet<>(Set.of(2, 3, 5, 7));
for (Integer prime : primes) {
System.out.println(prime * 2);
}
特点:
- 代码可读性高
- 不支持修改集合结构
- 线程不安全
3. forEach()方法[编辑 | 编辑源代码]
Java 8引入的默认方法,支持Lambda表达式:
Map<String, Integer> inventory = Map.of("Laptop", 5, "Phone", 10);
inventory.forEach((item, quantity) ->
System.out.printf("%s: %d in stock%n", item, quantity)
);
4. 列表迭代器(ListIterator)[编辑 | 编辑源代码]
List
特有的双向迭代器:
List<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
ListIterator<String> listIterator = colors.listIterator(colors.size());
// 逆向遍历
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
5. Stream API[编辑 | 编辑源代码]
函数式编程风格的遍历:
List<Product> products = getProducts();
products.stream()
.filter(p -> p.getPrice() > 100)
.map(Product::getName)
.forEach(System.out::println);
性能比较[编辑 | 编辑源代码]
下表比较不同集合类型的遍历性能(时间复杂度):
集合类型 | Iterator | For-Each | forEach() | Stream |
---|---|---|---|---|
O(n) | O(n) | O(n) | O(n) | ||||
O(n) | O(n) | O(n) | O(n) | ||||
O(n) | O(n) | O(n) | O(n) | ||||
O(n) | O(n) | O(n) | O(n log n) |
因为Stream的排序操作
并发修改异常处理[编辑 | 编辑源代码]
当遍历时修改集合会抛出
ConcurrentModificationException
,解决方案:
- 使用迭代器的方法
remove()
- 使用等并发集合
CopyOnWriteArrayList
- 先收集要修改的元素,遍历结束后再处理
List<String> data = new ArrayList<>(List.of("A", "B", "C"));
List<String> toRemove = new ArrayList<>();
for (String item : data) {
if (item.equals("B")) {
toRemove.add(item);
}
}
data.removeAll(toRemove);
最佳实践[编辑 | 编辑源代码]
1. 读操作:优先使用for-each循环
2. 修改操作:必须使用
Iterator
3. 复杂处理:考虑Stream API
4. 并行处理:使用
parallelStream()
实际案例[编辑 | 编辑源代码]
电商平台购物车结算:
public BigDecimal calculateTotal(Cart cart) {
return cart.getItems().stream()
.map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
数据库查询结果处理:
try (ResultSet rs = statement.executeQuery("SELECT * FROM users")) {
List<User> users = new ArrayList<>();
while (rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
users.forEach(user -> sendWelcomeEmail(user));
}
常见问题[编辑 | 编辑源代码]
进阶主题[编辑 | 编辑源代码]
- 自定义迭代器实现接口
Iterable
- 使用Spliterator进行并行遍历
- 深度比较不同JDK版本的遍历性能差异
{{Tip|在Java 21+中,考虑使用SequencedCollection的新遍历方法如
reversed()
}