循环遍历 Java 集合中元素的方法总结
循环遍历 Java 集合中元素的方法
在 Java 中,有多种方法可以遍历集合中的元素。以下是几种常见的遍历方法及其优缺点:
1. for-each 循环
-
语法:
for (ElementType element : collection) { // 处理 element }
-
适用场景:所有集合类型(如
List
、Set
、Map
等)。 -
优点:
- 语法简洁,易于阅读。
- 遍历效率高,与迭代器类似。
-
缺点:
- 无法在遍历过程中修改集合(会抛出
ConcurrentModificationException
)。
- 无法在遍历过程中修改集合(会抛出
-
注意事项:
- 基于迭代器实现,与迭代器共享
fail-fast
机制。
- 基于迭代器实现,与迭代器共享
2. Iterator 迭代器
-
语法:
Iterator<ElementType> iterator = collection.iterator(); while (iterator.hasNext()) { ElementType element = iterator.next(); // 处理 element // 可以安全地在遍历中删除元素 // iterator.remove(); }
-
适用场景:所有集合类型。
-
优点:
- 可安全地在遍历过程中删除元素(通过
remove()
方法)。
- 可安全地在遍历过程中删除元素(通过
-
缺点:
- 无法添加元素(除非使用
ListIterator
)。
- 无法添加元素(除非使用
-
注意事项:
fail-fast
机制:检测到结构修改时抛出异常。- 需手动管理迭代器生命周期。
3. 普通 for 循环
-
语法:
for (int i = 0; i < list.size(); i++) { ElementType element = list.get(i); // 处理 element }
-
适用场景:
List
或数组。 -
优点:
- 直接通过索引访问,效率高(尤其适合随机访问)。
-
缺点:
- 仅适用于有序集合(如
List
)。 - 遍历中修改集合可能导致越界异常。
- 仅适用于有序集合(如
-
注意事项:
- 需预先获取集合长度(
size()
),适合需要索引操作的场景。
- 需预先获取集合长度(
4. Java 8+ Stream API
-
语法:
collection.stream().forEach(element -> { // 处理 element });
-
适用场景:所有集合类型。
-
优点:
- 支持链式操作(
filter
、map
、reduce
等)。 - 可并行处理(
parallel()
)。
- 支持链式操作(
-
缺点:
- 性能开销较大(创建流对象)。
- 对简单遍历可能不够高效。
-
注意事项:
- 惰性求值:需终端操作(如
forEach()
)触发执行。 - 不支持直接修改集合。
- 惰性求值:需终端操作(如
5. ListIterator
-
语法:
ListIterator<ElementType> listIterator = list.listIterator(); while (listIterator.hasNext()) { ElementType element = listIterator.next(); // 处理 element // 可以安全地在遍历中增删元素 // listIterator.remove(); // listIterator.add(newElement); }
-
适用场景:
List
类型。 -
优点:
- 双向遍历(正向/反向)。
- 支持在遍历中增删元素。
-
缺点:
- 仅适用于
List
。 - 逻辑较复杂。
- 仅适用于
-
注意事项:
- 维护游标位置需谨慎,避免越界。
- 与迭代器类似,有
fail-fast
机制。
6. Lambda 表达式
-
语法:
collection.forEach(element -> { // 处理 element });
-
适用场景:所有集合类型。
-
优点:
- 代码简洁。
- 与 Stream API 结合使用更强大。
-
缺点:
- 对简单遍历可能冗余。
- 需 Java 8+ 支持。
-
注意事项:
- 需配合
forEach()
或 Stream API 使用。 - 无法在遍历中修改集合。
- 需配合
表格总结优缺点
方法 | 适用场景 | 优点 | 缺点 | 注意事项 |
---|---|---|---|---|
for-each循环 | 所有集合类型 | - 语法简洁 - 遍历效率高(与迭代器类似) | - 无法在遍历过程中修改集合(会抛出 ConcurrentModificationException ) | - 基于迭代器实现,与迭代器共享 fail-fast 机制 |
Iterator迭代器 | 所有集合类型 | - 可安全地在遍历中删除元素(remove() ) | - 无法添加元素(除非使用 ListIterator ) | - fail-fast 机制:检测到结构修改时抛出异常- 需手动管理迭代器生命周期 |
普通for循环 | List或数组 | - 直接通过索引访问,效率高(尤其适合随机访问) | - 仅适用于有序集合(如 List )- 遍历中修改集合可能导致越界异常 | - 需预先获取集合长度(size() ),适合需要索引操作的场景 |
Java 8+ Stream API | 所有集合类型 | - 支持链式操作(filter/map/reduce 等)- 可并行处理( parallel() ) | - 性能开销较大(创建流对象) - 对简单遍历可能不够高效 | - 惰性求值:需终端操作(如 forEach() )触发执行- 不支持直接修改集合 |
ListIterator | List类型 | - 双向遍历(正向/反向) - 支持在遍历中增删元素 | - 仅适用于 List - 逻辑较复杂 | - 维护游标位置需谨慎,避免越界 - 与迭代器类似,有 fail-fast 机制 |
Lambda表达式 | 所有集合类型 | - 代码简洁 - 与 Stream API 结合使用更强大 | - 对简单遍历可能冗余 - 需 Java 8+ 支持 | - 需配合 forEach() 或 Stream API 使用- 无法在遍历中修改集合 |
选择建议
-
简单遍历:
- for-each循环:语法简洁,适合只读操作。
- 普通for循环:需索引访问时(如
List
)优先选择。
-
遍历中修改集合:
- Iterator:安全删除元素(通过
remove()
)。 - ListIterator:双向遍历或需增删元素时使用。
- Iterator:安全删除元素(通过
-
复杂操作(过滤/映射/聚合):
- Stream API:结合 Lambda 表达式,代码更简洁且功能强大。
-
多线程环境:
- 使用
CopyOnWriteArrayList
等线程安全集合,避免ConcurrentModificationException
。
- 使用
通过合理选择遍历方法,可以提升代码的可读性和执行效率。