1. 概述

本文深入解析 Java 中的核心语法结构之一——for 循环。它是我们处理重复操作的利器,广泛应用于数组遍历、集合迭代、计数循环等场景。

掌握 for 的各种写法和适用场景,不仅能写出更简洁的代码,还能避免一些隐藏的“坑”。✅

2. 基础 for 循环

基础 for 循环是最经典的循环结构,通过初始化、条件判断和步进操作三部分控制循环执行。

其语法结构如下:

for (初始化; 布尔表达式; 步进操作) 
    语句;

来看一个最简单的例子:

for (int i = 0; i < 5; i++) {
    System.out.println("Simple for loop: i = " + i);
}

输出:

Simple for loop: i = 0
Simple for loop: i = 1
Simple for loop: i = 2
Simple for loop: i = 3
Simple for loop: i = 4

⚠️ 注意:for 循环的三个部分(初始化、条件、步进)都是可选的。如果全部省略,就构成了一个无限循环

for ( ; ; ) {
    // 无限循环,等价于 while(true)
}

这种写法虽然少见,但在某些事件监听或守护线程中仍有使用场景,记得配合 break 使用,否则会一直跑下去 ❌。

2.1. 带标签的 for 循环

当遇到多层嵌套循环时,普通的 breakcontinue 只能作用于最内层循环,这时候就需要带标签的 for 循环来精准控制跳转。

看下面这个例子:

aa: for (int i = 1; i <= 3; i++) {
    if (i == 1)
      continue;
    bb: for (int j = 1; j <= 3; j++) {
        if (i == 2 && j == 2) {
            break aa;
        }
        System.out.println(i + " " + j);
    }
}

输出:

2 1
3 1
3 2
3 3

解释一下:

  • 外层循环标记为 aa,内层为 bb
  • i=1 时,continue 跳过本次外层循环
  • i=2j=2 时,break aa 直接跳出整个外层循环,不再执行后续迭代

✅ 这种写法在处理复杂嵌套逻辑时非常有用,但也要注意别滥用,否则会影响代码可读性。

3. 增强 for 循环(for-each)

从 Java 5 开始引入的增强 for 循环(也叫 for-each),让遍历数组和集合变得简单粗暴

语法如下:

for (元素类型 变量名 : 集合或数组)
    语句;

它背后的核心思想是:

items 中的每个元素,将其赋值给 item 变量,然后执行循环体。

来看个数组遍历的例子:

int[] intArr = { 0, 1, 2, 3, 4 }; 
for (int num : intArr) {
    System.out.println("Enhanced for-each loop: i = " + num);
}

输出:

Enhanced for-each loop: i = 0
Enhanced for-each loop: i = 1
...

3.1. 遍历常见数据结构

增强 for 循环适用于所有实现了 Iterable 接口的类型,比如:

List 遍历:

List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {
    System.out.println(item);
}

Set 遍历:

Set<String> set = new HashSet<>(Arrays.asList("X", "Y", "Z"));
for (String item : set) {
    System.out.println(item);
}

Map 遍历(通过 entrySet):

Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println("Key: " + entry.getKey() + " - Value: " + entry.getValue());
}

⚠️ 注意:增强 for 循环虽然简洁,但有几点限制:

  • 无法在遍历过程中修改集合(会抛 ConcurrentModificationException
  • 无法获取当前索引(除非自己维护计数器)
  • 不适合需要反向遍历或跳跃访问的场景

3.2. Iterable.forEach() 与 Lambda

从 Java 8 开始,Iterable 接口新增了 forEach() 方法,结合 Lambda 表达式,让遍历更加函数式。

其默认实现如下:

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

可以看到,它底层依然是基于增强 for 循环实现的。

使用示例:

List<String> names = new ArrayList<>();
names.add("Larry");
names.add("Steve");
names.add("James");
names.add("Conan");
names.add("Ellen");

names.forEach(name -> System.out.println(name));

输出:

Larry
Steve
James
Conan
Ellen

✅ 优点:

  • 代码更简洁,语义更清晰
  • 支持方法引用:names.forEach(System.out::println);
  • 更容易与 Stream API 集成

⚠️ 缺点:

  • 调试不如传统循环直观
  • 异常处理稍显麻烦(Lambda 中 checked exception 需要包装)

4. 总结

循环类型 适用场景 是否可修改集合 是否支持索引
基础 for 需要索引、反向遍历、复杂控制
增强 for (for-each) 简单遍历数组/集合
Iterable.forEach 函数式风格,结合 Lambda 使用

选择哪种 for 循环,关键看你的使用场景:

  • 想快速打印集合?用 forEach()
  • 要边遍历边删元素?用 Iterator ❌(别用增强 for)
  • 需要精确控制循环变量?基础 for 最靠谱 ✅

所有示例代码已托管至 GitHub:https://github.com/baeldung/core-java-modules/tree/master/core-java-lang-syntax


原始标题:Java For Loop | Baeldung