while、do-while 和 for 用来控制循环,它们也叫作迭代语句(iteration statement)。迭代语句会重复执行,直到起控制作用的布尔表达式结果变为 false。while 循环的格式如下:
while(Boolean-expression)
statement
在循环刚开始时会计算一次布尔表达式的值,而在下一次迭代之前会再计算一次。
下面的例子会一直生成随机数,直到满足特定条件为止:
// control/WhileTest.java
// 演示while循环
public class WhileTest {
static boolean condition() {
boolean result = Math.random() < 0.99;
System.out.print(result + ", ");
return result;
}
public static void main(String[] args) {
while(condition())
System.out.println("Inside 'while'");
System.out.println("Exited 'while'");
}
}
/* 输出(最开始和最后的5行):
true, Inside 'while'
true, Inside 'while'
true, Inside 'while'
true, Inside 'while'
true, Inside 'while'
...________...________...________...________...
true, Inside 'while'
true, Inside 'while'
true, Inside 'while'
true, Inside 'while'
false, Exited 'while'
*/
condition() 方法使用了 Math 库里的静态方法 random()。该方法会生成一个范围为 0~1(包括0,但不包括1)的 double 值。返回的结果是一个布尔值,通过比较操作符<
产生。while条件表达式的意思是“重复执行循环里的主体语句,直到 condition() 方法返回 false ”。
5.3.1 do-while
do-while 语句的格式如下:
do
statement
while(Boolean-expression);
while 和 do-while 的唯一的区别是 do-while 中的语句至少会执行一次,即便表达式的第一次计算结果就是false。而在 while 中,如果条件表达式第一次得出的值就是 false,则它的语句根本不会执行。在日常使用中,while 要比 do-while 更常用一些。
5.3.2 for
for 循环可能是最常用的迭代形式,这种循环在第一次迭代前会先进行初始化,然后再进行条件测试。在每次迭代结束后,还会有某些形式的“步进”。for 循环的格式如下:
for(initialization; Boolean-expression; step)
statement
上面的初始化表达式(initialization)、布尔表达式(Boolean-expression)和步进(step)都可以为空。每次迭代前会测试布尔表达式。只要结果是 false,就不再循环,而是执行跟在 for 循环后面的语句。每次循环结束,都会执行一次步进。
for 循环常用于执行 “计数” 任务:
// control/ListCharacters.java
// 展示所有的小写ASCII字母
public class ListCharacters {
public static void main(String[] args) {
for(char c = 0; c < 128; c++)
if(Character.isLowerCase(c))
System.out.println("value: " + (int)c +
" character: " + c);
}
}
/* 输出(前10行):
value: 97 character: a
value: 98 character: b
value: 99 character: c
value: 100 character: d
value: 101 character: e
value: 102 character: f
value: 103 character: g
value: 104 character: h
value: 105 character: i
value: 106 character: j
...
*/
注意变量 c 是在使用时被定义的,它发生在 for 循环的控制表达式里,而不是在 main() 方法开始的地方。 c 的作用域就是 for 循环控制的语句范围内。
像 C 这种传统的过程式语言要求所有变量都在程序开始的地方定义。当编译器创建它们的时候,会为这些变量分配空间。而在 Java 和C++
中,你可以把变量声明分散在整个程序里,在真正需要的时候才定义。这样的编程风格更自然,也更易于理解。1
1在早期的语言中,设计者所做的大量决定是为了让编译器开发者的工作更轻松。而在现代语言中,大多数设计决策是为了让编程语言的使用者工作更轻松,尽管有时会有妥协——这一般最终会成为语言设计者的遗憾。
上面的程序使用了 java.lang.Character 包装器类,它不仅可以把char基本类型的值包装进对象,还提供了其他一些有用的工具。这里用到的静态方法 isLowerCase() 可以检测出相关字符是否为小写字母。
5.3.3 逗号操作符
逗号操作符不是逗号分隔符,逗号分隔符用来分隔声明和函数的不同参数,而 Java 里唯一用到逗号操作符的地方就是 for 循环的控制表达式。在控制表达式的初始化和步进部分,都可以使用一系列由逗号分隔的语句,而这些语句会按先后顺序执行。
通过使用逗号操作符,你可以在 for 语句里定义多个变量,但它们必须是相同的类型。
// control/CommaOperator.java
public class CommaOperator {
public static void main(String[] args) {
for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) {
System.out.println("i = " + i + " j = " + j);
}
}
}
/* 输出:
i = 1 j = 11
i = 2 j = 4
i = 3 j = 6
i = 4 j = 8
*/
以上 for 语句里的 int 参数定义包括 i 和 j,在初始化部分可以定义同一个类型的任意数量的变量。在控制表达式里定义多个变量的能力只限于 for 循环,在其他任何选择或迭代语句中都不能使用这种方式。
在初始化和步进部分,语句都是按先后顺序执行的。