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

前言

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

一、基础遍历方式

1. 基本for循环

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

  • 优点:索引操作灵活,适合需频繁访问索引的场景(如修改元素位置)。
  • 缺点 :代码冗余,无法遍历SetMap;遍历中修改集合会抛出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接口的集合(如ListSetMap.entrySet())。
核心思路 :隐式迭代器,无需显式管理索引。
特点

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

二、进阶遍历方式

3. Iterator迭代器

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

  • 优点 :支持遍历中安全删除元素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+)

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

  • 优点 :支持filtermapreduce等高阶操作;可并行处理(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的惰性求值与中间操作/终端操作的区别。
相关推荐
m0_3807438740 分钟前
为 OpenAI 兼容接口配置教程
开发语言·python·node.js
凤山老林1 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端
博傅1 小时前
Spring 核心原理
java·后端·spring
yurenpai(27届找实习中)1 小时前
从零读懂 AI 智能客服(一):模块职责与 SSE 聊天链路(后端架构)
java·人工智能·架构·langchain4j
万邦科技Lafite1 小时前
阿里巴巴拍立淘按图搜索商品API返回值实践:提升用户购物满意度的关键措施
开发语言·api·开放api·电商开放平台·京东开放平台
陈皮波比茶2 小时前
Swagger
java
小闫BI设源码2 小时前
Elasticsearch面试必看:如何让客户端精准选择节点高效执行请求?
java·elasticsearch·面试宝典·深入解析
小小龙学IT2 小时前
Qt 6 跨平台开发完全指南:从信号槽机制到实际项目落地
开发语言·qt
leisoo80972 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
摇滚侠2 小时前
《SpringBoot 3:入门与应用实战》第 5 章 使用 Spring Boot 阅读笔记 9
java·spring boot·笔记