【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的惰性求值与中间操作/终端操作的区别。
相关推荐
hrrrrb1 分钟前
【Rust】枚举和模式匹配
开发语言·rust
沐雨潇竹13 分钟前
使用定时器监视当前PID 如果当前程序关闭 UI_Core.exe 也随之自动关闭实现方法
开发语言·qt·ui
大锦终20 分钟前
【C++】红黑树
c语言·开发语言·数据结构·c++
星霜旅人30 分钟前
Java并发编程
java
咛辉1 小时前
什么是RDD.RDD的创建方式
开发语言
阿月浑子20211 小时前
[C#]Task.Run()和Task.Factory.StartNew()对比(腾讯元宝)
开发语言·c#
天上掉下来个程小白1 小时前
缓存套餐-01.Spring Cache入门案例
java·redis·spring·缓存·springboot·springcache
深色風信子1 小时前
Eclipse 插件开发 6 右键菜单
java·ide·eclipse·右键菜单
I烟雨云渊T1 小时前
iOS瀑布流布局的实现(swift)
开发语言·ios·swift
网安INF1 小时前
Apache Shiro 1.2.4 反序列化漏洞(CVE-2016-4437)
java·网络安全·apache