【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的惰性求值与中间操作/终端操作的区别。
相关推荐
程序员张34 小时前
Maven编译和打包插件
java·spring boot·maven
ybq195133454315 小时前
Redis-主从复制-分布式系统
java·数据库·redis
weixin_472339465 小时前
高效处理大体积Excel文件的Java技术方案解析
java·开发语言·excel
小毛驴8506 小时前
Linux 后台启动java jar 程序 nohup java -jar
java·linux·jar
枯萎穿心攻击6 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
DKPT6 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
Eiceblue7 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
好奇的菜鸟8 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
m0_555762908 小时前
Matlab 频谱分析 (Spectral Analysis)
开发语言·matlab
程序视点8 小时前
Window 10文件拷贝总是卡很久?快来试试这款小工具,榨干硬盘速度!
windows