Java 实例 – 集合遍历(实战指南)

Java 实例 – 集合遍历:从入门到精通的实战指南

在 Java 开发中,集合(Collection)是处理数据最常用的数据结构之一。无论是从数据库读取用户列表,还是处理配置项、日志记录,我们几乎每天都在与集合打交道。而集合的核心操作之一,就是遍历——也就是逐个访问集合中的每一个元素。

如果你刚接触 Java,可能会觉得“遍历”听起来很简单:for 循环不就能搞定?但随着项目复杂度上升,你会遇到并发修改异常、性能瓶颈、代码冗长等问题。这时候,掌握多种遍历方式,理解每种方式的适用场景,就变得至关重要。

本文将以实际代码为例,带你系统掌握 Java 实例 – 集合遍历 的各种方法,从基础到进阶,帮你写出更优雅、更安全、更高效的代码。

为什么要学习集合遍历?

想象一下你有一本厚厚的通讯录,里面记录了 1000 个联系人。现在你要找出所有姓“张”的人。如果逐个翻页查看,效率极低;但如果你能用“快速查找”功能,瞬间筛选出结果,那效率就高多了。

集合遍历的本质,就是“快速查找”工具的使用。不同的遍历方式,就像不同的查找工具。有的快但不能修改,有的灵活但容易出错。掌握它们,才能在开发中游刃有余。

1. for-each 循环:最简洁的遍历方式

for-each 循环(也叫增强 for 循环)是 Java 5 引入的语法糖,它让遍历集合变得极其简单。它是大多数初学者首选的方式。

代码示例:遍历 List

import java.util.ArrayList;

import java.util.List;

public class ForEachExample {

public static void main(String[] args) {

// 创建一个包含 5 个名字的列表

List names = new ArrayList<>();

names.add("Alice");

names.add("Bob");

names.add("Charlie");

names.add("Diana");

names.add("Eve");

// 使用 for-each 循环遍历集合

for (String name : names) {

System.out.println("当前名字:" + name);

}

}

}

中文注释说明:

List names:声明一个字符串类型的列表,用于存储名字。

names.add(...):向列表中添加元素。

for (String name : names):这是 for-each 循环语法,name 是当前元素的变量名,names 是被遍历的集合。

System.out.println(...):打印当前名字。

优点:

代码简洁,可读性强。

避免手动索引操作,不容易出错。

缺点:

无法在遍历时修改集合(如删除元素),否则会抛出 ConcurrentModificationException。

2. Iterator 迭代器:安全修改集合的利器

当你需要在遍历过程中删除或添加元素时,for-each 就会“罢工”,抛出异常。这时,Iterator 就派上用场了。

代码示例:使用 Iterator 删除偶数

import java.util.*;

public class IteratorExample {

public static void main(String[] args) {

// 创建一个整数列表

List numbers = new ArrayList<>();

numbers.add(1);

numbers.add(2);

numbers.add(3);

numbers.add(4);

numbers.add(5);

numbers.add(6);

// 获取迭代器

Iterator iterator = numbers.iterator();

// 使用 while 循环配合 Iterator

while (iterator.hasNext()) {

Integer num = iterator.next(); // 获取下一个元素

// 如果是偶数,就删除

if (num % 2 == 0) {

iterator.remove(); // 安全删除当前元素

}

}

// 输出结果

System.out.println("删除偶数后的列表:" + numbers);

}

}

中文注释说明:

iterator.hasNext():判断是否还有下一个元素。

iterator.next():返回下一个元素并移动指针。

iterator.remove():唯一安全删除元素的方法,必须通过迭代器调用。

重要提醒:

不能在 for-each 中调用 remove(),否则会触发并发修改异常。

Iterator.remove() 是唯一合法的删除方式。

3. 传统 for 循环:索引控制的灵活性

当需要根据索引进行操作,比如访问前一个元素、跳过某些位置、或执行条件判断时,传统 for 循环就非常有优势。

代码示例:遍历 List 并访问前后元素

import java.util.*;

public class TraditionalForExample {

public static void main(String[] args) {

List fruits = Arrays.asList("苹果", "香蕉", "橙子", "葡萄", "草莓");

// 使用传统 for 循环,通过索引遍历

for (int i = 0; i < fruits.size(); i++) {

String current = fruits.get(i); // 获取当前元素

String next = ""; // 声明下一个元素

// 判断是否是最后一个元素

if (i < fruits.size() - 1) {

next = fruits.get(i + 1); // 获取下一个元素

} else {

next = "无";

}

System.out.println("当前水果:" + current + ",下一个水果:" + next);

}

}

}

中文注释说明:

fruits.size():获取集合长度。

fruits.get(i):通过索引获取元素,适用于 List。

i < fruits.size() - 1:防止索引越界。

适用场景:

需要访问前后元素。

需要跳过某些索引(如每隔一个处理一次)。

需要倒序遍历。

4. Stream API:函数式编程的优雅之选

Java 8 引入的 Stream API 让集合遍历进入函数式编程时代。它不只遍历,还能过滤、映射、聚合,代码更简洁、更强大。

代码示例:使用 Stream 筛选并打印名字长度大于 4 的人

import java.util.*;

import java.util.stream.Collectors;

public class StreamExample {

public static void main(String[] args) {

List names = Arrays.asList("Alice", "Bob", "Charlie", "Diana", "Eve", "Frank");

// 使用 Stream API 进行链式操作

List filteredNames = names.stream()

.filter(name -> name.length() > 4) // 筛选出长度大于 4 的名字

.collect(Collectors.toList()); // 收集结果为列表

// 遍历输出

filteredNames.forEach(name -> System.out.println("名字:" + name));

}

}

中文注释说明:

stream():将集合转换为流。

filter(...):过滤条件,只保留满足条件的元素。

Collectors.toList():将流中的元素收集回列表。

forEach(...):遍历并执行操作。

优势:

支持链式调用,逻辑清晰。

可并行处理(parallelStream()),适合大数据。

代码更接近自然语言,可读性高。

5. Map 遍历:键值对的处理方式

Map 是键值对集合,遍历方式也更丰富。常见有三种方式:entrySet、keySet、forEach。

代码示例:遍历 Map 的三种方式

import java.util.*;

public class MapTraversalExample {

public static void main(String[] args) {

Map scores = new HashMap<>();

scores.put("张三", 85);

scores.put("李四", 92);

scores.put("王五", 78);

// 方式一:使用 entrySet + for-each

System.out.println("方式一:entrySet 遍历");

for (Map.Entry entry : scores.entrySet()) {

System.out.println(entry.getKey() + " 的成绩是:" + entry.getValue());

}

// 方式二:使用 keySet + for-each

System.out.println("\n方式二:keySet 遍历");

for (String key : scores.keySet()) {

System.out.println(key + " 的成绩是:" + scores.get(key));

}

// 方式三:使用 forEach + Lambda

System.out.println("\n方式三:forEach + Lambda");

scores.forEach((name, score) -> System.out.println(name + " 的成绩是:" + score));

}

}

中文注释说明:

entrySet():返回键值对集合,适合同时获取 key 和 value。

keySet():返回所有键的集合,适合只关心 key。

forEach(...):Java 8 新增,支持 Lambda 表达式。

推荐使用:

需要同时获取 key 和 value:用 entrySet。

只需要 key:用 keySet。

代码简洁且不关心性能:用 forEach。

总结与建议

通过本文的 Java 实例 – 集合遍历 实战讲解,我们系统学习了五种主要遍历方式:

方式

适用场景

是否支持修改

优点

缺点

for-each

简单遍历

否(会抛异常)

代码简洁

不能安全删除

Iterator

需要删除元素

安全删除

语法稍复杂

传统 for 循环

索引操作

灵活控制

代码较长

Stream API

数据处理链

否(默认)

功能强大,可读性高

学习成本略高

Map 遍历

键值对处理

视方式而定

多样选择

选择需谨慎

实用建议:

初学者优先掌握 for-each 和 Iterator。

中级开发者应熟悉 Stream API,提升代码质量。

避免在遍历时直接修改集合,除非使用 Iterator.remove()。

Map 遍历时优先使用 entrySet,避免重复 get。

掌握这些技巧后,你将不再为“如何遍历集合”而烦恼。每一次遍历,都是一次对代码质量的提升。

记住,代码不仅仅是“能运行”,更要“好维护、易扩展”。而这一切,都始于对集合遍历的深刻理解。