3.2.4 for循环
前面介绍while循环时,有一个名叫year的整型变量频繁出现,它是控制循环进出的关键要素。无论哪一种while写法,都存在3处与year有关的操作,分别是“year=0”“year<limit”“year++”。第一个“year=0”用来给该变量赋初始值,第二个“year<limit”则为是否退出循环的判断条件,第三个“year++”用于该变量的自增操作。这3处语句结合起来才能实现循环的有限次数处理,而非无限次数的运转。换句话说,要想实现一个标准的循环结构,就必须具备上述的3种基本操作。于是Java设计了新的for循环,意图让形态规整的for语句取代结构散乱的while语句。
for循环的书写格式形如“for (式子A;式子B;式子C;) { /*这里是循环的内部代码*/ }”。其中,式子A是初始化语句,在首次进入循环时执行;式子B是循环的判断条件,当B成立时继续循环,当B不成立时退出循环;式子C一般是变量的自增或自减操作,在开始下一次循环之前执行。仍以前述的唤醒游戏为例,使用for语句改写后的循环代码如下(完整代码见本章源码的src\com\control\process\ForLoop.java):
System.out.println("长夜漫漫,无心睡眠,请给他设定一个睡醒的年限"); Scanner scan=new Scanner(System.in); // 从控制台接收输入文本 int limit=scan.nextInt(); // nextInt方法表示接收一个整数,以回车键结尾 int year; // for (式子A; 式子B; 式子C;)的三个式子A、B、C说明如下 // 式子A在首次进入循环时执行 // 式子B是循环的判断条件,B成立时继续循环,不成立时退出循环 // 式子C在开始下一次循环之前执行 // 注意,每次循环结束之后,先执行式子C,再判断式子B for (year=0; year<limit; year++) { System.out.println("已经过去的年份:"+year); } System.out.println("他足足睡了这么多年:"+year);
从以上代码可见,for循环把3种基本操作放到了同一行,大大缩减了代码行数。仅仅3行for语句,等价于以下十几行的while循环代码:
year=0; if (year<limit) { while (true) { // 开始循环处理 System.out.println("已经过去的年份:"+year); year++; if (year<limit) { // 年份未达到条件,继续循环 continue; } else { // 年份已达到条件,退出循环 break; } } }
不过精简代码的代价是缺乏灵活性。for语句的条件判断默认在每次循环开始之前执行,倘若希望在循环内部的指定位置判断是否继续循环,仍然要把式子B的判断条件挪到循环里面,此时for语句原先给式子B的地方可以留空。于是挪动条件判断之后的for循环代码变成了下面这样(完整代码见本章源码的src\com\control\process\ForLoop2.java):
for (int year=0; ; year++) { System.out.println("已经过去的年份:"+year); if (year >= limit) { // 这里判断能否跳出循环 System.out.println("他足足睡了这么多年:"+year); break; // 跳出循环,即跳到for循环的右花括号之后 } else { continue; // 继续下一次循环。此时先执行year++,再执行循环内部语句 } }
既然式子B原来的位置允许留空,那么只要处理得当,式子A和式子C的位置也是允许留空的。3个位置同时留空后的for循环代码示例如下(完整代码见本章源码的src\com\control\process\ ForLoop3.java):
int year=0; // 把式子A挪到整个循环的前面 for (; ; ) { // for语句后面的3个位置全部留空 System.out.println("已经过去的年份:"+year); if (year >= limit) { // 这里判断能否跳出循环 System.out.println("他足足睡了这么多年:"+year); break; // 跳出循环,即跳到for循环的右花括号之后 } else { year++; // 把式子C挪到continue之前 continue; // 继续下一次循环。此时先执行year++,再执行循环内部语句 } }
可是一旦紧跟for语句之后的3个位置全部留空,这个for就变得毫无特点了,此时的“for (; ; )”完全等价于“while (true)”。所以说,具体采取哪种循环形式,还得根据实际的业务要求来定夺。