Java 实例 – for 和 foreach循环使用(长文解析)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
循环的基石作用
在 Java 开发中,循环是构建程序逻辑的核心工具之一。无论是遍历数据集合、执行重复性操作,还是实现复杂算法,循环结构都扮演着关键角色。本文将通过实例解析 for 循环 和 foreach 循环 的使用场景、语法差异及优化技巧,帮助开发者在不同需求下选择最合适的方案。
for 循环:灵活控制的“瑞士军刀”
基本语法与工作原理
for 循环提供了完整的控制能力,允许开发者定义初始化、条件判断和迭代逻辑。其语法结构如下:
for (初始化; 条件判断; 迭代表达式) {
// 循环体
}
形象比喻:可以将其想象为工厂流水线,初始化是启动机器,条件判断是质检环节,迭代是传送带的移动,而循环体是生产线上的具体操作。
实例 1:基础计数器
for (int i = 0; i < 5; i++) {
System.out.println("当前计数:" + i);
}
// 输出:0 到 4,共 5 次循环
实例 2:多变量控制
for (int a = 0, b = 10; a < 5; a++, b -= 2) {
System.out.println("a=" + a + " | b=" + b);
}
// 输出:a 递增,b 递减,同时控制
foreach 循环:简洁遍历的“导游模式”
语法特性与适用场景
foreach 循环(也称增强型 for 循环)专为遍历数组或集合而设计,语法更简洁:
for (数据类型 变量名 : 集合/数组) {
// 循环体
}
核心优势:无需关注索引或迭代器,只需声明变量接收当前元素。
实例 3:数组遍历
int[] numbers = {3, 1, 4, 1, 5};
for (int num : numbers) {
System.out.println("元素值:" + num);
}
// 输出数组所有元素
实例 4:集合遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println("欢迎:" + name);
}
// 输出列表中每个姓名
for 与 foreach 的对比:选择指南
核心差异总结
特性 | for 循环 | foreach 循环 |
---|---|---|
灵活性 | 支持复杂迭代逻辑(如多变量控制) | 仅支持简单遍历 |
索引访问 | 可直接获取索引 | 无法直接获取索引 |
性能 | 稍优(直接操作索引) | 稍逊(内部仍需索引计算) |
适用场景 | 需要精细控制流程的场景 | 纯遍历需求,无需修改集合内容 |
具体选择建议
- 选择 for 循环:当需要动态修改循环条件、操作索引或处理多维数组时。
- 选择 foreach 循环:当只需按顺序访问元素且无需索引时,可提升代码可读性。
实例 5:修改数组元素的对比
// 使用 for 循环修改数组元素
int[] arr = {10, 20, 30};
for (int i = 0; i < arr.length; i++) {
arr[i] *= 2; // 可直接通过索引修改
}
// 使用 foreach 无法直接修改元素
for (int num : arr) {
num *= 2; // 仅修改局部变量,原数组不变!
}
进阶技巧与常见问题
1. 嵌套循环的优化
在遍历二维数组时,可结合 for 和 foreach 实现高效代码:
int[][] matrix = {
{1, 2},
{3, 4, 5}
};
// 外层 for 控制行索引,内层 foreach 遍历列元素
for (int i = 0; i < matrix.length; i++) {
for (int num : matrix[i]) {
System.out.println("行 " + i + " 的元素:" + num);
}
}
2. 集合遍历时的“ConcurrentModificationException”
当通过 foreach 遍历集合时,若在循环体内修改集合(如添加/删除元素),会抛出此异常。解决方案包括:
- 使用迭代器显式控制:
Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("删除条件")) { iterator.remove(); // 安全删除 } }
- 复制临时集合进行遍历:
for (String item : new ArrayList<>(list)) { // ... }
3. 性能优化建议
- 预分配集合容量:遍历前确保集合内存已分配(如
ArrayList
的ensureCapacity()
)。 - 避免在循环体内执行高耗时操作:如网络请求或复杂计算,可考虑异步处理。
实战案例:统计文本词频
需求描述
统计一段文本中各单词的出现次数,并输出前 3 高频词。
解决方案
import java.util.*;
public class WordCounter {
public static void main(String[] args) {
String text = "Java is powerful. Java is flexible. Learn Java today!";
// 步骤 1:分割文本为单词数组
String[] words = text.split("\\W+");
// 步骤 2:统计词频
Map<String, Integer> frequencyMap = new HashMap<>();
for (String word : words) { // 使用 foreach 遍历单词
frequencyMap.put(word, frequencyMap.getOrDefault(word, 0) + 1);
}
// 步骤 3:排序并取前 3
List<Map.Entry<String, Integer>> entries = new ArrayList<>(frequencyMap.entrySet());
entries.sort((a, b) -> b.getValue().compareTo(a.getValue()));
// 步骤 4:输出结果
for (int i = 0; i < Math.min(3, entries.size()); i++) { // 使用 for 控制输出次数
Map.Entry<String, Integer> entry = entries.get(i);
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
输出结果:
Java: 3
is: 2
powerful: 1
结论
通过本文的实例解析,开发者可以清晰理解 for 循环 和 foreach 循环 在 Java 中的核心作用与差异。关键点总结如下:
- for 循环 是灵活的“瑞士军刀”,适合需要精细控制索引或执行复杂逻辑的场景。
- foreach 循环 是简洁的“导游模式”,适用于纯粹的遍历需求,提升代码可读性。
- 实战中需结合场景选择工具,并注意性能优化与异常处理技巧。
建议读者通过实际项目练习,逐步掌握两种循环的深度用法。例如,尝试用 for 循环实现斐波那契数列生成,或用 foreach 实现 CSV 文件的行遍历与数据解析。通过不断实践,循环结构将成为你编程道路上得心应手的工具。