Jakob Jenkov 发布于 2024-04-18
Java 的 for 循环用于重复执行一组 Java 操作。只要某个条件为真,for 循环就会不断重复执行一段代码块。下面是一个简单的 Java for 循环示例:
for(int i = 0; i < 10; i++) {
System.out.println("i is: " + i);
}
这是一个标准的 Java for 循环。在 for 关键字后的括号 () 中,包含三个由分号 ; 分隔的语句。
- 第一个语句声明了一个名为
i的int变量,并将其初始化为0。该语句仅在for循环开始时执行一次。 - 第二个语句将变量
i的值与10进行比较。如果i小于10,则再次执行for循环体。该语句在每次循环重复前都会被执行。 - 第三个语句对
i的值进行递增(i++)。该语句在每次循环体执行完毕后运行一次。
上述 for 循环的结果是:循环体共执行 10 次,分别对应 i 从 0 到 9 的值。
实际上,你并不一定需要使用花括号 {} 包裹 for 循环体。如果你省略了花括号,则只有 for 循环语句之后的第一条 Java 语句会被视为循环体。例如:
for(int i = 0; i < 10; i++)
System.out.println("i is 1: " + i); // 在循环内执行
System.out.println("second line"); // 在循环结束后执行
在这个例子中,只有第一个 System.out.println() 语句在 for 循环内部执行;第二个 System.out.println() 语句在 for 循环结束后才执行。
忘记为 for 循环体加上花括号是一个常见错误。因此,养成始终使用花括号包裹循环体的习惯是个好做法。
循环初始化器、条件和循环后操作
如前所述,for 循环括号内包含三个由分号分隔的语句。以下是前面示例中这三个语句的展示:
for(int i = 0; i < 10; i++) {
System.out.println("I is: " + i);
}
这三个语句在 for 循环执行过程中扮演不同的角色:
- 循环初始化器(Loop initializer)
- 循环条件(Loop condition)
- 循环后操作(Post iteration operation)
下面将逐一详细说明。
循环初始化器
循环初始化器语句只在 for 循环开始前执行一次。通常用于初始化循环条件中使用的变量或对象。例如,在以下代码中(加粗部分为初始化器):
for(int i = 0; i < 10; i++) {
System.out.println("i is: " + i);
}
初始化器声明了一个 int 类型的变量 i 并赋初值为 0。
注意:循环初始化器是可选的。以下是一个没有初始化器的
for循环示例:
MyLoop loop = new MyLoop(10);
for( ; loop.loopAgain() ; loop.iterationDone()) {
}
这里使用一个对象来维护控制循环的状态。当然,这个对象也可以在初始化器中声明,此处只是为了说明可以省略初始化器。
你还可以在初始化器中同时声明多个变量,例如:
for(int i = 0, n = 10; i < n; i++) {
}
这里同时声明了两个变量:用作计数器的 i 和作为边界值的 n。注意,此时循环条件比较的是 i 和 n,而非常量。
条件
条件语句是 for 循环括号中的第二个语句。它是一个布尔表达式,结果必须为 true 或 false。如果结果为 true,则继续执行下一次循环;如果为 false,则终止循环,并跳转到循环体之后的第一条语句。
例如,以下 for 循环中加粗的部分就是条件语句:
for(int i = 0; i < 10; i++) {
}
循环后操作
第三个语句是循环后操作(post iteration operation),在每次循环体执行完毕后运行。通常用于更新控制循环条件的变量,比如递增计数器。
例如:
for(int i = 0; i < 10; i++) {
}
这里的 i++ 就是循环后操作。它在每次循环结束后将 i 增加 1,而条件语句会检查 i 是否仍小于 10。
注意:循环后操作也是可选的。例如:
MyLoop loop = new MyLoop(10);
for( ; loop.loopAgain(); ) {
}
Java 的 for-each 循环
从 Java 5 开始,引入了一种 for 循环的变体,称为 for-each 循环。示例如下:
String[] strings = {"one", "two", "three"};
for(String aString : strings) {
System.out.println(aString);
}
注意这里的 String 数组 strings。在 for-each 循环中,括号内声明了一个 String 类型的变量 aString。在每次迭代中,该变量会依次绑定到数组中的每个元素。循环次数等于数组的长度。
for-each 循环也可用于泛型集合。
continue 命令
Java 提供了 continue 命令,可用于 for(以及 while)循环内部。当程序执行到 continue 时,JVM 会立即跳过当前循环体的剩余部分,直接进入下一次迭代。
注意:即使执行了
continue,当前迭代的“循环后操作”仍然会执行。
示例:
String[] strings = { "John", "Jack", "Abraham", "Jennifer", "Ann" };
int wordsStartingWithJ = 0;
for(int i = 0; i < strings.length; i++) {
if(! strings[i].toLowerCase().startsWith("j")) {
continue;
}
wordsStartingWithJ++;
}
此例中,若字符串不以字母 j 开头,则跳过后续代码,直接进入下一次循环;否则,计数器 wordsStartingWithJ 加 1。
continue 同样适用于 for-each 循环:
String[] strings = { "John", "Jack", "Abraham", "Jennifer", "Ann" };
int wordsStartingWithJ = 0;
for(String aString : strings) {
if(! aString.toLowerCase().startsWith("j")) {
continue;
}
wordsStartingWithJ++;
}
逻辑完全相同,只是语法略有不同。
break 命令
break 命令也可在 for(及 while)循环中使用。一旦执行 break,JVM 会立即退出整个循环,即使循环条件仍为真,也不会再执行后续迭代。
示例:
String[] strings = { "John", "Jack", "Abraham", "Jennifer", "Ann" };
int wordsStartingWithJ = 0;
for(int i = 0; i < strings.length; i++) {
if(strings[i].toLowerCase().startsWith("j")) {
wordsStartingWithJ++;
}
if(wordsStartingWithJ >= 3) {
break;
}
}
当找到第 3 个以 j 开头的单词时,break 被触发,循环立即终止。
同样,break 也适用于 for-each 循环:
String[] strings = { "John", "Jack", "Abraham", "Jennifer", "Ann" };
int wordsStartingWithJ = 0;
for(String aString : strings) {
if(aString.toLowerCase().startsWith("j")) {
wordsStartingWithJ++;
}
if(wordsStartingWithJ >= 3) {
break;
}
}
Java for 循环中的变量可见性
在 for 循环的括号或循环体内声明的变量,其作用域仅限于该循环体内。这一点对 for-each 循环同样适用。
例如:
for(int i = 0; i < 10; i++) {
String iAsNo = String.valueOf(i);
}
变量 i 和 iAsNo 只能在循环体内访问,循环外部无法引用它们。
同样,在 for-each 循环中:
String[] strings = {"one", "two", "three"};
for(String aString : strings) {
System.out.println(aString);
}
由于 aString 是在 for-each 循环括号内声明的,因此它只能在循环体内使用。