【Java基础】Java集合遍历方式

前言

在Java编程中,集合(Collection)是存储和操作对象的核心工具。遍历集合是开发者最频繁的操作之一,但不同场景下选择合适的遍历方式至关重要。

一、基础遍历方式

1. 基本for循环

适用场景 :仅适用于List等有序集合(如ArrayList、LinkedList)。
核心思路 :通过索引直接访问元素。
特点:

  • 优点:索引操作灵活,适合需频繁访问索引的场景(如修改元素位置)。
  • 缺点 :代码冗余,无法遍历Set或Map;遍历中修改集合会抛出ConcurrentModificationException异常。
java 复制代码
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));
}

2. 增强for循环(for-each)

适用场景 :所有实现Iterable接口的集合(如List、Set、Map.entrySet())。
核心思路 :隐式迭代器,无需显式管理索引。
特点:

  • 优点:语法简洁,可读性强;无需处理索引或迭代器。
  • 缺点:无法在遍历中修改集合(添加/删除元素会抛出异常);无法获取元素索引。
java 复制代码
List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {
    System.out.println("元素: " + item);
}

二、进阶遍历方式

3. Iterator迭代器

适用场景 :所有集合类型(List、Set、Map)。
核心思路 :通过迭代器逐个访问元素,支持安全删除。
特点:

  • 优点 :支持遍历中安全删除元素 (iterator.remove());兼容所有集合类型。
  • 缺点:代码复杂度较高;无法直接添加元素或获取索引。
java 复制代码
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(); // 安全删除元素
    }
}

4. ListIterator(双向遍历)

适用场景 :仅适用于List接口的实现类。
核心思路 :支持正向/反向遍历,可获取当前索引并插入元素。
特点:

  • 优点 :双向遍历(next()/previous());支持索引操作和插入。
  • 缺点:实现复杂,适用场景有限。
java 复制代码
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());
}

三、函数式与并行遍历

5. Stream API(Java 8+)

适用场景 :复杂操作(过滤、映射、并行处理)。
核心思路 :函数式编程范式,支持链式调用。
特点:

  • 优点 :支持filter、map、reduce等高阶操作;可并行处理(parallel())。
  • 缺点:性能开销较高;不支持直接修改集合。
java 复制代码
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);

6. forEach方法(Java 8+)

适用场景 :所有集合类型,结合Lambda表达式使用。
核心思路 :基于Collection.forEach(Consumer)接口。
特点:

  • 优点:语法简洁,与Lambda结合自然。
  • 缺点 :本质是Iterator,无法在遍历中修改集合。
java 复制代码
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表达式

选择建议

  1. 简单遍历 :优先使用增强for循环 或 forEach。
  2. 需要删除元素 :使用**Iterator**(避免ConcurrentModificationException)。
  3. 双向遍历或插入 :使用**ListIterator**。
  4. 复杂操作(过滤、并行) :使用**Stream API**。
  5. 索引操作 :使用基本for循环 或 ListIterator。

五、注意事项

1. ConcurrentModificationException的根源

  • 原因 :在遍历过程中直接修改集合(如通过remove()或add())会破坏迭代器的内部状态。
  • 解决方案 :
    • 使用Iterator.remove()安全删除元素。
    • 遍历前创建临时集合存储需删除的元素,遍历后统一处理。

2. 并行遍历的性能考量

  • Stream.parallel():适合大数据量场景,但需注意线程安全与任务分割开销。

六、总结

Java集合遍历方式的选择需结合具体场景,从可读性 、安全性 、性能等维度综合评估。掌握每种方法的核心特性,能显著提升代码质量和开发效率。无论是基础循环还是函数式编程,理解其底层原理(如迭代器机制、流处理)是进阶的关键。


延伸阅读:

  • Fail-Fast机制与ConcurrentModificationException的深层原理。
  • Stream的惰性求值与中间操作/终端操作的区别。
相关推荐
FinelyYang9 分钟前
考试系统简答题 AI 阅卷:覆盖度驱动、异步评分与人机协同落地实践
java·大数据·人工智能
天外飞雨道沧桑10 分钟前
我在浏览器里练了一个 792 参数的大模型,它学会了补全 JavaScript
开发语言·javascript·ai·ecmascript·ai编程
hhhjhl14 分钟前
Yup 跨端三方库仓颉适配全流程
java·开发语言
运维行者_26 分钟前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
用户31268748772034 分钟前
Java 对象内存布局:压缩指针、对齐填充与 JOL 实测
java
东华果汁哥1 小时前
【Spring AI 实战】从零开始调用大模型接口,构建 Java AI 应用
java·人工智能·spring
“AI国潮设计-小江”1 小时前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc
Song_RsHt1 小时前
Redis 与微服务,什么场景下无可替代
java·redis·后端·学习·微服务
学长毕设2 小时前
基于SpringBoot的建筑材料管理系统-附源码
java·spring boot·后端
lhbweilai2 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机