在Java编程中,集合(Collection)是存储和操作对象的核心工具。遍历集合是开发者最频繁的操作之一,但不同场景下选择合适的遍历方式至关重要。
for
循环适用场景:仅适用于List
等有序集合(如ArrayList
、LinkedList
)。
核心思路:通过索引直接访问元素。
特点:
Set
或Map
;遍历中修改集合会抛出ConcurrentModificationException
异常。List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (int i = 0; i < list.size(); i++) {
System.out.println("索引 " + i + ": " + list.get(i));
}
for
循环(for-each
)适用场景:所有实现Iterable
接口的集合(如List
、Set
、Map.entrySet()
)。
核心思路:隐式迭代器,无需显式管理索引。
特点:
List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {
System.out.println("元素: " + item);
}
Iterator
迭代器适用场景:所有集合类型(List
、Set
、Map
)。
核心思路:通过迭代器逐个访问元素,支持安全删除。
特点:
iterator.remove()
);兼容所有集合类型。List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println("当前元素: " + item);
if (item.equals("B")) {
iterator.remove(); // 安全删除元素
}
}
ListIterator
(双向遍历)适用场景:仅适用于List
接口的实现类。
核心思路:支持正向/反向遍历,可获取当前索引并插入元素。
特点:
next()
/previous()
);支持索引操作和插入。List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
ListIterator<String> iterator = list.listIterator();
// 正向遍历
System.out.println("正向遍历:");
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 反向遍历
System.out.println("反向遍历:");
while (iterator.hasPrevious()) {
System.out.println(iterator.previous());
}
Stream API
(Java 8+)适用场景:复杂操作(过滤、映射、并行处理)。
核心思路:函数式编程范式,支持链式调用。
特点:
filter
、map
、reduce
等高阶操作;可并行处理(parallel()
)。List<String> list = Arrays.asList("A", "B", "C");
// 简单遍历
list.stream().forEach(System.out::println);
// 过滤后遍历
list.stream()
.filter(s -> s.length() > 1)
.map(String::toUpperCase)
.forEach(System.out::println);
forEach
方法(Java 8+)适用场景:所有集合类型,结合Lambda表达式使用。
核心思路:基于Collection.forEach(Consumer)
接口。
特点:
Iterator
,无法在遍历中修改集合。List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
list.forEach(item -> {
if (item.equals("B")) {
System.out.println("找到元素B");
}
});
方法 | 适用集合类型 | 支持索引 | 支持删除 | 代码简洁性 | 适用场景 |
---|---|---|---|---|---|
基本for |
List |
是 | 否 | 低 | 需要索引操作的场景 |
增强for |
所有Iterable |
否 | 否 | 高 | 简单遍历,无需修改集合 |
Iterator |
所有集合 | 否 | 是 | 中 | 安全删除元素的场景 |
ListIterator |
List |
是 | 是 | 低 | 双向遍历或插入元素 |
Stream API |
所有集合 | 否 | 否 | 高(函数式) | 复杂操作(过滤、映射、并行) |
forEach |
所有集合 | 否 | 否 | 高 | 简单遍历,结合Lambda表达式 |
for
循环或 forEach
。Iterator
**(避免ConcurrentModificationException
)。ListIterator
**。Stream API
**。for
循环或 ListIterator
。ConcurrentModificationException
的根源remove()
或add()
)会破坏迭代器的内部状态。Iterator.remove()
安全删除元素。Stream.parallel()
:适合大数据量场景,但需注意线程安全与任务分割开销。Java集合遍历方式的选择需结合具体场景,从可读性、安全性、性能等维度综合评估。掌握每种方法的核心特性,能显著提升代码质量和开发效率。无论是基础循环还是函数式编程,理解其底层原理(如迭代器机制、流处理)是进阶的关键。
延伸阅读:
Fail-Fast
机制与ConcurrentModificationException
的深层原理。Stream
的惰性求值与中间操作/终端操作的区别。