编辑
一、问题描述
最近发现一个有趣的问题,在Java中如何从一个多层嵌套循环中退出呢?
例如下面,有两层循环,break只能退出第一个for循环,不能直接跳出第二个for循环外面。
public static void main(String[] args) { for (String s1: sArray1) { for (String s2 : sArray2) { if (某个条件){ // 执行事件后退出 break; // 这样只退出了最里的for循环 } } } }
二、解决方案
那该怎么解决这个问题呢?答案是可以用break+label的语法,例子如下:
public class test { public static void main(String[] args) { String[] s1={"1","2","3","4","5"}; String[] s2={"6","7","8","9","10"}; loop:for (int i = 0; i < s1.length; i++) { for (int j = 0; j < s2.length; j++) { if (j > 2) { System.out.println("使用break退出循环"); break loop; } System.out.println(i+"---"+j); } } System.out.println("执行结束"); } }
首先在for循环前加标签,如例子中的loop,然后在for循环内break label(如本例的loop),就会跳出该label指定的for循环。
当然,这种方案小伙伴们见的比较少,我们也可以采用return的方式退出循环。
public class test { public static void main(String[] args) { String[] s1={"1","2","3","4","5"}; String[] s2={"6","7","8","9","10"}; for (int i = 0; i < s1.length; i++) { for (int j = 0; j < s2.length; j++) { if (j > 2) { System.out.println("使用return退出循环"); return; } System.out.println(i+"---"+j); } } System.out.println("执行结束"); } }
但使用return和使用break是有区别的,return后就不会继续执行后面的代码了,而使用break只是跳出循环,后面的代码还是会继续去执行。
所以最后一段代码的执行结束部分不会被执行。
三、goto关键字
这种break的方式,其实类似于c语言中的goto语法,比如下面的代码:
#include<stdio.h> int n=0; int main(void) { printf("input a string: "); loop: if (getchar()!='\n') { n++; goto loop; } printf("output: %d\n",n); }
在C/C++中,goto常被用于跳出多重循环。但goto 语句的使用往往会使程序的可读性降低,所以 Java 不允许 goto 跳转。在Java中,goto也是作为关键字被保留的,但这个关键字没有任何作用,只是为了将来可能的扩展,防止使用goto作为程序中的标识符。
四、Java中的标签
我们前面使用使用"break loop;"的方式跳出多重循环,实际上loop是Java的自定义自定义标签,Java 中的标签是为循环设计的,是为了在多重循环中方便的使用 break 和 coutinue 而设计的。(这也是Java中唯一用到标签的地方!)正是由于这个原因,Java 的标签只能定义在三种循环 (for() {}, do{} while(), while() {}) 的开始位置,否则编译器会报告说找不到标签。
在循环前面加上标签,就好像给循环起了个名字。而后在循环中使用 break 或者 continue 语句的时候,就可以带上这个标签做为参数,指明跳出 (break) 或者继续 (continue)标签对应的哪个循环,如"break mylabel;"、"continue mylabel;"。
五、总结
虽然break/continue+标签的用法平时很少见到,但在Java的源码中不时会看到,如在ThreadPoolExecutor类中的addWorker方法就使用了"continue 标签"。因此这也是Java程序设计的一种技巧,需要加以掌握。