首頁 > 軟體

Java流程控制語句最全彙總(下篇)

2023-01-16 14:02:53

前文

本章是關於Java流程控制語句的最全彙總,本篇為彙總下篇。

流程是人們生活中不可或缺的一部分,它表示人們每天都在按照一定的流程做事。

比如出門搭車、上班、下班、搭車回家。這其中的步驟是有順序的。

程式設計也需要有流程控制語句來完成使用者的要求,根據使用者的輸入決定程式要進入什麼流程,即“做什麼”以及“怎麼做”等。

從結構化程式設計角度出發,程式有 3 種結構:順序結構、選擇結構和迴圈結構。

若是在程式中沒有給出特別的執行目標,系統則預設自上而下一行一行地執行該程式,這類程式的結構就稱為順序結構。

到目前為止,我們所編寫的程式都屬於順序結構。

但是事物的發展往往不會遵循早就設想好的軌跡進行,因此,所設計的程式還需要能夠具有在不同的條件下處理不同問題以及當需要進行一些相同的重複操作時,如何能省時省力地解決問題的能力。

在本章中,我們將對 Java 程式中的上述3種流程結構進行學習。

初學者應該對本章的每個小節進行仔細閱讀、思考,這樣才能達到事半功倍的效果。

Java foreach語句的用法

foreach 迴圈語句是 Java 1.5 的新特徵之一,在遍歷陣列、集合方面,foreach 為開發者提供了極大的方便。

foreach 迴圈語句是 for 語句的特殊簡化版本,主要用於執行遍歷功能的迴圈。

foreach 迴圈語句的語法格式如下:

for(型別 變數名:集合) {
    語句塊;
}

其中,“型別”為集合元素的型別,“變數名”表示集合中的每一個元素,“集合”是被遍歷的集合物件或陣列。

每執行一次迴圈語句,迴圈變數就讀取集合中的一個元素,其執行流程如圖 1 所示。

圖 1 foreach 迴圈語句的執行流程圖

例 1

假設有一個陣列,採用 for 語句遍歷陣列的方式如下:

// 宣告並初始化陣列
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for----");
// for語句
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Count is:" + numbers[i]);
}

上述第 2 行語句宣告並初始化了 7 個元素陣列集合,目前大家只需要知道當初始化陣列時,要把相同型別的元素放到 {…} 中並且用逗號分隔(,)即可。

關於陣列集合會在教學後面詳細介紹,這裡我們只需要大概瞭解就可以。

numbers.length 是獲得陣列的長度,length 是陣列的屬性,numbers[i] 是通過陣列下標存取陣列元素。

那麼採用 for-each 迴圈語句遍歷陣列的方式如下:

// 宣告並初始化int陣列
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for each----");
// for-each語句
for (int item : numbers) {
    System.out.println("Count is:" + item);
}

從範例中可以發現,item 不是迴圈變數,它儲存了集合中的元素,for-each 語句將集合中的元素一一取出來,並儲存到 item 中,這個過程中不需要使用迴圈變數,通過陣列下標存取陣列中的元素。

可見 for-each 語句在遍歷集合的時候要簡單方便得多。

例 2

String[] urls = { "http://c.biancheng.net/java", "http://c.biancheng.net/c", "http://c.biancheng.net/golang/" };
// 使用foreach迴圈來遍歷陣列元素
// 其中book將會自動迭代每個陣列元素
for (String url : urls) {
    System.out.println(url);
}

從上面程式可以看出,使用 foreach 迴圈遍歷陣列元素時無須獲得陣列長度,也無須根據索引來存取陣列元素。

foreach 迴圈和普通迴圈不同的是,它無須迴圈條件,無須迴圈迭代語句,這些部分都由系統來完成,foreach 迴圈自動迭代陣列的每個元素,當每個元素都被迭代一次後,foreach 迴圈自動結束。

當使用 foreach 迴圈來迭代輸出陣列元素或集合元素時,通常不要對迴圈變數進行賦值,雖然這種賦值在語法上是允許的,但沒有太大的實際意義,而且極容易引起錯誤。

例如下面程式。

String[] urls = { "http://c.biancheng.net/java", "http://c.biancheng.net/c", "http://c.biancheng.net/golang/" };
// 使用foreach迴圈來遍歷陣列元素,其中 book 將會自動迭代每個陣列元素
for (String url : urls) {
    url = "https://c.biancheng.net";
    System.out.println(url);
}
System.out.println(urls[0]);

執行上邊程式,將看到如下結果:

https://c.biancheng.net

https://c.biancheng.net

https://c.biancheng.net

https://c.biancheng.net/java

從上面執行結果來看,由於在 foreach 迴圈中對陣列元素進行賦值,結果導致不能正確遍歷陣列元素,不能正確地取出每個陣列元素的值。

而且當再次存取第一個陣列元素時,發現陣列元素的值依然沒有改變。

不難看出,當使用 foreach 來迭代存取陣列元素時,foreach 中的迴圈變數相當於一個臨時變數,系統會把陣列元素依次賦給這個臨時變數,而這個臨時變數並不是陣列元素,它只是儲存了陣列元素的值。

因此,如果希望改變陣列元素的值,則不能使用這種 foreach 迴圈。

使用 foreach 迴圈迭代陣列元素時,並不能改變陣列元素的值,因此不要對 foreach 的迴圈變數進行賦值。

例 3

在一個字串陣列中儲存了幾種程式語言,現在將這些程式語言遍歷輸出。

foreach 語句的實現程式碼如下:

public static void main(String[] args) {
    String[] languages={"Java","ASP.NET","Python","C#","PHP"};
    System.out.println("現在流行的程式語言有:");
    // 使用 foreach 迴圈語句遍歷陣列
    for(String lang:languages) {
        System.out.println(lang);
    }
}

在迴圈體執行的過程中,每回圈一次,會將 languages 陣列中的一個元素賦值給 lang 變數,直到遍歷 languages 陣列中所有元素,迴圈終止。

該程式執行後的結果如下所示。

現在流行的程式語言有:
Java
ASP.NET
Python
C#
PHP

Java return語句

return 關鍵字並不是專門用於結束迴圈的,return 語句用於終止函數的執行或退出類的方法,並把控制權返回該方法的呼叫者。

如果這個方法帶有返回型別,return 語句就必須返回這個型別的值;如果這個方法沒有返回值,可以使用沒有表示式的 return 語句。

return 語句的一般語法格式如下:

return 與方法相同型別的變數;

如果一個方法使用了 return 語句並且後面跟有該方法返回型別的值,那麼呼叫此方法後,所得到的結果為該方法返回的值。

例 1

當用戶輸入兩個 double 型別的數值後需要計算這兩個數值之和,而這兩個運算元是可以變動的,但是求和的功能是不變的,這時就需要定義一個方法,只要在需要求和時呼叫該方法即可,該方法將計算之後的結果返回。程式碼如下:

import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("請輸入運算元1:");
        double num1 = input.nextDouble(); // 獲取使用者輸入的運算元1
        System.out.println("請輸入運算元2:");
        double num2 = input.nextDouble(); // 獲取使用者輸入的運算元2
        double d = sum(num1, num2);
        System.out.println(num1 + "+" + num2 + "=" + d);
    }
    /**
     * 建立sum() 方法,返回double 型別的數值
     *
     * @param i 運算元1
     * @param j 運算元2
     * @return 兩個運算元之和
     */
    public static double sum(double i, double j) {
        double sum = i + j;
        return sum;
    }
}

當用戶輸入兩個 double 型別的數值後,程式呼叫 sum() 方法。

該方法有兩個引數,分別表示使用者輸入的運算元 1 和運算元 2。

在呼叫該方法時,只需要將使用者輸入的兩個數值傳遞過去即可,然後程式會執行 sum() 方法,對這兩個數求和,並使用 return 語句將計算得出的結果返回。

在 main() 方法中,同樣需要使用 double 型別的變數來接收 sum() 方法返回的值,即變數 d 為計算後的結果。

執行後的結果如下所示:

請輸入運算元1:
500
請輸入運算元2:
203
500.0+203.0=703.0
請輸入運算元1:
5.66
請輸入運算元2:
3.0158
5.66+3.0158=8.6758

Java break語句:跳出迴圈

某些時候需要在某種條件出現時強行終止迴圈,而不是等到迴圈條件為 false 時才退出迴圈。

此時,可以使用 break 來完成這個功能。

break 用於完全結束一個迴圈,跳出迴圈體。不管是哪種迴圈,一旦在迴圈體中遇到 break,系統將完全結束該回圈,開始執行迴圈之後的程式碼。

在 Java 中,break 語句有 3 種作用,分別是:在 switch 語句中終止一個語句序列、使用 break 語句直接強行退出迴圈和使用 break 語句實現 goto 的功能。

使用 break 語句直接強行退出迴圈(break 不帶標籤)

可以使用 break 語句強行退出迴圈,忽略迴圈體中的任何其他語句和迴圈的條件判斷。

在迴圈中遇到 break 語句時,迴圈被終止,在迴圈後面的語句重新開始。

例 1

小明參加了一個 1000 米的長跑比賽,在 100 米的跑道上,他迴圈地跑著,每跑一圈,剩餘路程就會減少 100 米,要跑的圈數就是迴圈的次數。

但是,在每跑完一圈時,教練會問他是否要堅持下去,如果回答 y,則繼續跑,否則表示放棄。

使用 break 語句直接強行退出迴圈的範例如下:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in); // 定義變數儲存小明的回答
    String answer = ""; // 一圈100米,1000米為10圈,即為迴圈的次數
    for (int i = 0; i < 10; i++) {
        System.out.println("跑的是第" + (i + 1) + "圈");
        System.out.println("還能堅持嗎?"); // 獲取小明的回答
        answer = input.next(); // 判斷小明的回答是否為y?如果不是,則放棄,跳出迴圈
        if (!answer.equals("y")) {
            System.out.println("放棄");
            break;
        }
        // 迴圈之後的程式碼
        System.out.println("加油!繼續!");
    }
}

該程式執行後的效果如下所示:

跑的是第1圈
還能堅持嗎?
y
加油!繼續!
跑的是第2圈
還能堅持嗎?
y
加油!繼續!
跑的是第3圈
還能堅持嗎?
n
放棄

儘管 for 迴圈被設計為從 0 執行到 10,但是當小明的回答不是 y 時,break 語句終止了程式的迴圈,繼續執行迴圈體外的程式碼,輸出“加油!繼續!”。

break 語句能用於任何 Java 迴圈中,包括人們有意設定的無限迴圈。

在一系列巢狀迴圈中使用 break 語句時,它將僅僅終止最裡面的迴圈。例如:

public static void main(String[] args) {
    // 外迴圈,迴圈5次
    for (int i = 0; i < 5; i++) {
        System.out.print("第" + (i + 1) + "次迴圈:");
        // 內迴圈,設計為迴圈10次
        for (int j = 0; j < 10; j++) {
            // 判斷j是否等於3,如果是,則終止迴圈
            if (j == 3) {
                break;
            }
            System.out.print("內迴圈的第" + (j + 1) + "次迴圈t");
        }
        System.out.println();
    }
}

該程式執行結果如下所示:

第1次迴圈:內迴圈的第1次迴圈 內迴圈的第2次迴圈 內迴圈的第3次迴圈
第2次迴圈:內迴圈的第1次迴圈 內迴圈的第2次迴圈 內迴圈的第3次迴圈
第3次迴圈:內迴圈的第1次迴圈 內迴圈的第2次迴圈 內迴圈的第3次迴圈
第4次迴圈:內迴圈的第1次迴圈 內迴圈的第2次迴圈 內迴圈的第3次迴圈
第5次迴圈:內迴圈的第1次迴圈 內迴圈的第2次迴圈 內迴圈的第3次迴圈

從程式執行結果來看,在內部迴圈中的 break 語句僅僅終止了所在的內部迴圈,外部迴圈沒有受到任何的影響。

注意:一個迴圈中可以有一個以上的 break 語句,但是過多的 break 語句會破壞程式碼結構。

switch 迴圈語句中的 break 僅影響 switch 語句,不會影響迴圈。

例 2

編寫一個 Java 程式,允許使用者輸入 6 門課程成績,如果錄入的成績為負則跳出迴圈;如果錄入 6 門合法成績,則計算已有成績之和。

使用 break 語句的實現程式碼如下:

public static void main(String[] args) {
    int score; // 每門課的成績
    int sum = 0; // 成績之和
    boolean con = true; // 記錄錄入的成績是否合法
    Scanner input = new Scanner(System.in);
    System.out.println("請輸入學生的姓名:");
    String name = input.next(); // 獲取使用者輸入的姓名
    for (int i = 1; i <= 6; i++) {
        System.out.println("請輸入第" + i + "門課程的成績:");
        score = input.nextInt();// 獲取使用者輸入的成績
        if (score < 0) { // 判斷使用者輸入的成績是否為負數,如果為負數,終止迴圈
            con = false;
            break;
        }
        sum = sum + score; // 累加求和
    }
    if (con) {
        System.out.println(name + "的總成績為:" + sum);
    } else {
        System.out.println("抱歉,分數錄入錯誤,請重新錄入!");
    }
}

執行程式,當用戶錄入的分數低於 0 時,則輸出“抱歉,分數錄入錯誤,請重新錄入!”資訊,否則列印學生的總成績。輸出結果如下所示。

請輸入學生的姓名:
zhangpu
請輸入第1門課程的成績:
100
請輸入第2門課程的成績:
75
請輸入第3門課程的成績:
-8
抱歉,分數錄入錯誤,請重新錄入!
請輸入學生的姓名:
zhangpu
請輸入第1門課程的成績:
100
請輸入第2門課程的成績:
68
請輸入第3門課程的成績:
73
請輸入第4門課程的成績:
47
請輸入第5門課程的成績:
99
請輸入第6門課程的成績:
84
zhangpu的總成績為:471

在該程式中,當錄入第 3 門課的成績時,錄入的成績為負數,判斷條件“score<0”為 true,執行“con=false”,用 con 來標記錄入是否有誤。

接著執行 break 語句,執行完之後程式並沒有繼續執行條件語句後面的語句,而是直接退出 for 迴圈。之後執行下面的條件判斷語句,判斷 boolean 變數的 con 是否為 true,如果為 true,則列印總成績;否則列印“抱歉,分數錄入錯誤,請重新錄入!”。

使用 break 語句實現 goto 的功能(break 帶標籤)

有時候,在巢狀很深的迴圈語句中會發生一些不可預料的事情。

此時可能更加希望跳到巢狀的所有迴圈語句之外。

通過新增一些額外的條件判斷實現各層迴圈的檢測很不方便。

幸運的是,Java 與 C++ 不同,Java 提供了一種帶標籤的 break 語句,用於跳出多重巢狀的迴圈語句。

break 語句可以實現 goto 的功能,並且 Java 定義了 break 語句的一種擴充套件形式來處理退出巢狀很深的迴圈這個問題。

通過使用擴充套件的 break 語句,可以終止執行一個或者幾個任意程式碼塊,這些程式碼塊不必是一個迴圈或一個 switch 語句的一部分

。同時這種擴充套件的 break 語句帶有標籤,可以明確指定從何處重新開始執行。

break 除了具有 goto 退出深層迴圈巢狀作用外,還保留了一些程式結構化的特性。

標籤 break 語句的通用格式如下:

break label;

label 是標識程式碼塊的標籤。

當執行這種形式的 break 語句時,控制權被傳遞出指定的程式碼塊。

被加標籤的程式碼塊必須包圍 break 語句,但是它不需要直接包圍 break 的塊。

也就是說,可以使用一個加標籤的 break 語句來退出一系列的巢狀塊,但是不能使用 break 語句將控制權傳遞到不包含 break 語句的程式碼塊。

用標籤(label)可以指定一個程式碼塊,標籤可以是任何合法有效的 Java 識別符號,後跟一個冒號。

加上標籤的程式碼塊可以作為 break 語句的物件,使程式在加標籤的塊的結尾繼續執行。

下面是使用帶標籤的break 語句的範例。

public class GotoDemo {
    public static void main(String[] args) {
        label: for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.println(j);
                if (j % 2 != 0) {
                    break label;
                }
            }
        }
    }
}

以上程式的執行結果為:

0
1

這裡的 label 是標籤的名稱,可以為 Java 語言中任意合法的識別符號。

標籤語句必須和迴圈匹配使用,使用時書寫在對應的迴圈語句的上面,標籤語句以冒號結束。

如果需要中斷標籤語句對應的迴圈,可以採用 break 後面跟標籤名的方式。

如在上面程式碼中,當 j 為 1 時,“j%2!=0”條件表示式成立,則 label 標籤所代表的最外層迴圈終止。

注意:通常緊跟 break 之後的標籤,必須在 break 所在迴圈的外層迴圈之前定義才有意義。

在 switch 語句中終止一個語句序列

在 switch 語句中終止一個語句序列,就是在每個 case 子句塊的最後新增語句“break;”,這個功能在《Java switch case》已經講過,這裡不在講述。

Java continue語句詳解

有時強迫一個迴圈提早反覆是有用的,也就是,你可能想要繼續執行迴圈,但是要忽略這次重複剩餘的迴圈體的語句,所以 Java 提供了 continue 語句。

continue 語句是 break 語句的補充。

本節主要講解 continue 語句。

與 break 語句一樣, 它將中斷正常的控制流程。

continue 語句將控制轉移到最內層迴圈的首部。

continue 語句是跳過迴圈體中剩餘的語句而強制執行下一次迴圈,其作用為結束本次迴圈,即跳過迴圈體中下面尚未執行的語句,接著進行下一次是否執行迴圈的判定。

continue 語句類似於 break 語句,但它只能出現在迴圈體中。

它與 break 語句的區別在於:continue 並不是中斷迴圈語句,而是中止當前迭代的迴圈,進入下一次的迭代。

簡單來講,continue 是忽略迴圈語句的當次迴圈。

注意:continue 語句只能用在 while 語句、for 語句或者 foreach 語句的迴圈體之中,在這之外的任何地方使用它都會引起語法錯誤。

在迴圈體中使用 continue 語句有兩種方式可以帶有標籤,也可以不帶標籤。語法格式如下:

continue //不帶標籤

continue label //帶標籤,label是標籤名

下面看一個範例,程式碼如下:

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < numbers.length; i++) {
    if (i == 3) {
        continue;
    }
    System.out.println("Count is: " + i);
}

在上述程式程式碼中,當條件 i==3 的時候執行 continue 語句,continue 語句會終止本次迴圈,迴圈體中 continue 之後的語句將不再執行,接著進行下次迴圈,所以輸出結果中沒有 3。程式執行結果如下:

Count is: 0
Count is: 1
Count is: 2
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9

帶標籤的 continue 語句範例程式碼如下:

public static void main(String[] args) {
    label1: for (int x = 0; x < 5; x++) {
        for (int y = 5; y > 0; y--) {
            if (y == x) {
                continue label1;
            }
            System.out.println(x+","+y);
        }
    }
    System.out.println("Game Over!");
}

預設情況下,continue 只會跳出最近的內迴圈(程式碼第 3 行的 for 迴圈),如果要跳出程式碼第 2 行的外迴圈,可以為外迴圈新增一個標籤 label1,然後在第 5 行的 continue 語句後面指定這個標籤 label1,這樣當條件滿足執行 continue 語句時,程式就會跳轉出外迴圈。

程式執行結果如下:

0,5
0,4
0,3
0,2
0,1
1,5
1,4
1,3
1,2
2,5
2,4
2,3
3,5
3,4
4,5
Game Over!

由於跳過了 x == y,因此下面的內容沒有輸出。

1,1
2,2
3,3
4,4

Java選擇結構和迴圈結構的總結

任何程式語言中最常見的程式結構就是順序結構。

順序結構就是程式從上到下逐行的執行,中間沒有任何判斷和跳轉。

如果 main 方法的多行程式碼之間沒有任何流程控制,則程式總是從上向下依次執行,排在前面的程式碼先執行,排在後面的程式碼後執行

。這意味著:如果沒有流程控制,Java 方法裡的語句是一個順序執行流,從上向下依次執行每條語句。

不論哪一種程式語言,都會提供兩種基本的流程控制結構:分支結構和迴圈結構。

分支結構用於實現根據條件來選擇性地執行某段程式碼,迴圈結構則用於實現根據迴圈條件重複執行某段程式碼。

Java 同樣提供了這兩種流程控制結構的語法,Java 提供了 if 和 switch 兩種分支語句,並提供了 while、do while 和 for 三種迴圈語句。

一般寫回圈語句時,分以下三步走:

  1. 定義初始值
  2. 設定判斷條件
  3. 初始值變化

除此之外,JDK5 還提供了一種新的迴圈:foreach 迴圈,能以更簡單的方式來遍歷集合、陣列的元素。

Java 還提供了 break、continue 和 return 來控制程式的迴圈結構,作用如下:

  • break:表示跳出當前層迴圈
  • continue:表示跳出本次迴圈,進入下一次迴圈
  • return:跳出當前方法的迴圈

當在實現某個功能語句時,如果需要通過某一個條件去判斷,則用選擇結構。

當實現某個功能需要通過迴圈去實現,則用迴圈結構。

當然迴圈和選擇是可以相互巢狀的。

到此這篇關於Java流程控制語句最全彙總(下篇)的文章就介紹到這了,其他兩個部分的內容(上、中篇)請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com