位元詩人 Java 控制流程教學:if / switch / while / for 範例整理

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

在 Java 中,程式不一定只能由上而下執行。透過控制結構(if、switch、迴圈),可以讓程式根據條件改變流程。

本文將介紹 Java 中幾種常見的控制結構,並透過簡單範例說明其基本用法。本文適合初學者快速掌握 Java 控制流程的基本寫法。

if 敘述

if 是最基本的選擇控制結構,只有在條件成立時,對應的程式碼區塊才會執行。

以下範例使用隨機數,並判斷該數值為奇數或偶數:

import java.util.Random;

public class MainProgram
{
    public static void main (String[] args)
    {
        var max = 10;
        var min = 1;

        var random = new Random();
        var n = random.nextInt(max - min + 1) + min;

        if (n % 2 == 0) {
            System.out.println(n + " is even");
        }
        else {
            System.out.println(n + " is odd");
        }
    }
}

switch 敘述

switch 也是一種選擇控制結構,適用於「值的比對」,語法上比多重 if-else 更簡潔。

需要特別注意的是,case 結尾若忘記加上 break,程式會繼續往下執行下一個 case,這種現象稱為 fallthrough。有時這是刻意設計,但更多時候會變成 bug。

以下範例依照星期幾輸出對應的訊息:

import java.util.Date;
import java.util.GregorianCalendar;

public class MainProgram
{
    public static void main (String[] args)
    {
        var now = new Date();
        var c = GregorianCalendar.getInstance();
        c.setTime(now);
        var dow = c.get(GregorianCalendar.DAY_OF_WEEK);

        switch (dow) {
            case 6:
            case 7:
                System.out.println("Weekend");
                break;
            case 5:
                System.out.println("Thanks God. It's Friday");
                break;
            case 3:
                System.out.println("Hump day");
                break;
            default:
                System.out.println("Week");
                break;
        }
    }
}

此範例中刻意使用了一次 fallthrough(6、7 共用邏輯),這是符合預期的設計,而非錯誤。

while 敘述

while 是基本的迴圈控制結構,只要條件成立,就會持續重複執行同一段程式碼。

var i = 1;
while (i <= 10) {
    System.out.println(i);
    ++i;
}

需要注意的是,如果結束條件設計不當,可能會導致無窮迴圈(infinite loop)。某些情況下這是刻意設計,但在多數情境中代表程式邏輯有誤。

for 敘述

使用計數器(Counter)

最常見的 for 迴圈形式,是使用計數器控制執行次數:

for (var i = 1; i <= 10; ++i) {
    System.out.println(i);
}

使用迭代器(Iterator)

另一種 for 迴圈用法需搭配集合(collection)或迭代器,這部分會在介紹容器時再進一步說明。

改變迴圈行進的敘述

break 敘述

break 可用來提早中斷迴圈:

for (var i = 1; i <= 10; ++i) {
    if (i > 5)
        break;

    System.out.println(i);
}

除了迴圈之外,switch 也依賴 break 來區隔各個 case

continue 敘述

continue 用來跳過當前這一輪迴圈剩餘的程式碼,直接進入下一次迭代:

for (var i = 1; i <= 10; ++i) {
    if (i % 2 != 0)
        continue;

    System.out.println(i);
}

(選讀) 終極密碼(Da Vinci Code)

前面的範例多半較為簡短,不容易體會控制結構在實際程式中的運作方式。本節透過一個較完整的範例,觀察如何組合這些控制結構。

這是一個常見的猜數字遊戲,其執行過程如下:

$ java MainProgram
Input a number (1, 100): 50
Too small
Input a number (50, 100): 75
Too big
Input a number (50, 75): 63
Too big
Input a number (50, 63): 57
Too big
Input a number (50, 57): 53
You guess right

建議先嘗試自行實作,再參考以下程式碼:

import java.util.Random;                                /*  1 */

public class MainProgram                                /*  2 */
{                                                       /*  3 */
    public static void main (String[] args)             /*  4 */
    {                                                   /*  5 */
        /* Set the initial range of a answer. */        /*  6 */
        var max = 100;                                  /*  7 */
        var min = 1;                                    /*  8 */

        /* Get a random answer
            between `min` and `max`. */
        var random = new Random();                      /*  9 */
        var answer =                                    /* 10 */
            random.nextInt(max - min + 1) + min;        /* 11 */

        while (true) {                                  /* 12 */
            /* Try to receive a valid input
                from the user. */
            int guess;                                  /* 13 */
            while (true) {                              /* 14 */
                /* Prompt the user for an input. */     /* 15 */
                var input = System                      /* 16 */
                    .console()                          /* 17 */
                    .readLine(                          /* 18 */
                        "Input a number "               /* 19 */
                        + "(" + min + ", "              /* 20 */
                              + max + "): ");           /* 21 */

                try {                                   /* 22 */
                    /* Parse the input. */              /* 23 */
                    guess = Integer.parseInt(input);    /* 24 */
                }                                       /* 25 */
                catch (Exception e) {                   /* 26 */
                    /* It fails to parse the input.
                        Skip to next iteration. */

                    System.out                          /* 27 */
                        .println(                       /* 28 */
                            "Invalid number: "          /* 29 */
                            + input);                   /* 30 */
                    continue;                           /* 31 */
                }                                       /* 32 */

                /* The guess out of range.
                    Skip to next iteration. */
                if (!(min <= guess && guess <= max)) {  /* 33 */
                    System.out                          /* 34 */
                        .println(                       /* 35 */
                            "Number out of range: "     /* 36 */
                            + guess);                   /* 37 */
                    continue;                           /* 38 */
                }                                       /* 39 */

                /* The guess is valid.
                    Exit the input loop. */
                break;                                  /* 40 */
            }                                           /* 41 */

            if (guess < answer) {                       /* 42 */
                System.out.println("Too small");        /* 43 */
                min = guess;                            /* 44 */
            }                                           /* 45 */
            else if (answer < guess) {                  /* 46 */
                System.out.println("Too big");          /* 47 */
                max = guess;                            /* 48 */
            }                                           /* 49 */
            else {                                      /* 50 */
                System.out.println("You guess right");  /* 51 */
                /* The guess is equal to the answer.
                    Exit the game loop. */
                break;                                  /* 52 */
            }                                           /* 53 */
        }                                               /* 54 */
    }                                                   /* 55 */
}                                                       /* 56 */

此範例的核心是一個遊戲迴圈(game loop),可分為兩個部分:

  1. 取得並驗證使用者輸入
  2. 判斷猜測結果並更新範圍

由於程式無法預先保證使用者輸入正確,因此使用一個內層迴圈持續讀取輸入,直到取得合法數值為止。輸入錯誤時,透過 continue 直接進入下一輪。

當輸入合法後,再依照猜測結果更新上下限,或在猜中時使用 break 結束整個遊戲。


若想進一步練習,可以嘗試擴充此程式,例如:

  • 由使用者決定數值範圍
  • 限制猜測次數
  • 加入分數機制(猜對加分、猜錯扣分)

這些延伸練習有助於熟悉控制結構在實務中的組合方式。

關於作者

位元詩人 (ByteBard) 是資訊領域碩士,喜歡用開源技術來解決各式各樣的問題。這類技術跨平台、重用性高、技術生命長。

除了開源技術以外,位元詩人喜歡日本料理和黑咖啡,會一些日文,有時會自助旅行。