一、問題描述
最近發現一個有趣的問題,在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程序設計的一種技巧,需要加以掌握。