為什麼你的程式會亂跑?搞懂Java的控制流程(Controlling Execution)【Thinking in Java筆記(3-1)】
在學習 Java 程式設計時,瞭解如何控制程式的執行流程是非常重要的。這篇文章將介紹 Java 中的條件語句和迴圈結構,幫助初學者掌握程式的控制邏輯。
true 和 false:布林世界的二元哲學
所有的條件判斷在 Java 裡都依賴布林值 true
或 false
。這裡沒有灰色地帶,也沒有「大概是對」這種藉口
嚴格的布林值規則
Java 很認真。它不像 C 語言那樣,會讓你用 0
當成 false
,然後任何非 0
都默默當作 true
在 Java 中,你不能寫 if(a)
來測試一個數字,而是要明確寫成 if(a != 0)
。語法潔癖?是的,這就是 Java
if-else 語句:基本結構
以下是 Java 裡最基本的 if-else
使用方式:
if (BooleanExpression)
statement
// 或
if (BooleanExpression)
statement
else
statement
小提醒:「statement」就是一行有效的 Java 指令,例如 System.out.println("Hello")
這種
實際應用:判斷數字大小
public class IfElse {
static int result = 0;
static void test(int testval, int target) {
if(testval > target)
result = +1;
else if(testval < target)
result = -1;
else
result = 0; // Match
}
public static void main(String[] args) {
test(10, 5);
System.out.println(result); // 輸出 1
test(5, 10);
System.out.println(result); // 輸出 -1
test(5, 5);
System.out.println(result); // 輸出 0
}
} /* Output:
1
-1
0
*/
在這段程式中,test()
方法會比較兩個數字大小,然後根據結果更新靜態變數 result
的值。main()
方法則呼叫這個方法來驗證各種情況,並列印出結果
這段程式碼的重點,不是展示什麼炫技操作,而是幫助你練好邏輯思考的基本功——這是每位寫程式的人都得經歷的第一道關卡
不再手動重複勞動:搞懂 Java 中的迴圈(Iteration)
寫程式的某種本質,就是「重複做事但不想重複敲鍵盤」。而 Java 的迴圈,就是為了讓你能優雅地重複某段邏輯,不必像古代人那樣 Ctrl+C / Ctrl+V
while 迴圈:條件控制的守門員
while
迴圈就像一個問問題的警衛:每次你想執行點什麼,它都會問你一次「條件還成立嗎?」如果你說「是」,它就讓你進去(執行一次迴圈內容),否則就把你請走(跳出迴圈)
語法
while(Boolean-expression)
statement
範例
來看看一個簡單的 while
迴圈範例,幫助你理解它怎麼運作:
public class WhileTest {
static boolean condition() {
boolean result = Math.random() < 0.99;
System.out.print(result + ", ");
return result;
}
public static void main(String[] args) {
while(condition())
System.out.println("Inside 'while'");
System.out.println("Exited 'while'");
}
}
這段程式碼的作用是:每次執行 condition()
都會有 99% 的機率返回 true
,因此 while
迴圈大多數時候會重複執行「Inside 'while'」這行,直到有一次運氣不好,產生的數大於等於 0.99,才會跳出來
condition()
方法會每次產生一個小於 1 的隨機數- 如果這個數字小於 0.99,就回傳
true
,迴圈繼續執行並印出「Inside 'while'」 - 如果回傳
false
(機率約 1%),就跳出迴圈,印出「Exited 'while'」
do-while 迴圈:你先幹了再說
do-while
是 Java 中唯一「保證至少執行一次」的迴圈。它不像其他迴圈那樣先檢查條件,而是先執行內容,再來問條件成不成立
最典型的例子就是「使用者輸入」。你總得先讓使用者輸入東西,然後才知道要不要再讓他輸入一次吧?像這樣的互動流程,就非常適合用 do-while
來寫
舉例來說:
- 建立登入畫面時,至少要顯示一次輸入介面,然後根據帳密正確與否判斷是否要重試
- 做選單系統時,先顯示一次選單,再依照使用者的選項進行後續動作
所以簡單來說:當你需要「一定要跑一次」的邏輯,do-while
就是你的好朋友
語法
do
statement
while (BooleanExpression);
範例
public class DoWhileExample {
public static void main(String[] args) {
int count = 0;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 5);
}
}
這段範例其實就像是在數人頭,只是用程式做的:
- 一開始
count
是 0,所以程式先執行一次do
區塊,印出「Count is: 0」 - 然後它會問:
count
小於 5 嗎?如果是,就再做一次 - 每次跑完一次,
count
就會加一,直到不小於 5 為止
實際用途呢?假設你有一個遊戲選單,第一次一定要先顯示給玩家看(不然他要按什麼?),然後只要玩家還沒選「退出」,你就繼續重複這個選單。這種「至少執行一次」的邏輯,就是 do-while
存在的意義
for 迴圈:井然有序的三段式重複器
在所有的迴圈中,for
是最常出現的老朋友。它的結構清晰明瞭,非常適合處理「我知道要做幾次」的情況。你可以把它想成一個待辦清單管理器:設定起點、決定何時停、每次該怎麼更新進度,通通一次搞定
這也正是它跟 while
的最大差異:while
比較像是你在等一個不確定的事件(像是等快遞送達),而 for
比較像是你要刷牙 3 次,就寫 for (次數)
然後開始刷,幾次就幾次,剛剛好
語法
for (初始化; 條件判斷; 更新步驟)
statement
- 初始化:設定計數器的初始值,通常像是
int i = 0
- 條件判斷:每次進入迴圈前檢查是否繼續,像是
i < 10
- 更新步驟:每次迴圈執行完後更新變數,像是
i++
三個部分都可以留空,這提供了需要時的靈活性。
範例
public class ListCharacters {
public static void main(String[] args) {
for(char c = 0; c < 128; c++)
if(Character.isLowerCase(c))
System.out.println("value: " + (int)c + " character: " + c);
}
} /* Output:
value: 97 character: a
value: 98 character: b
value: 99 character: c
value: 100 character: d
value: 101 character: e
value: 102 character: f
value: 103 character: g
value: 104 character: h
value: 105 character: i
value: 106 character: j
...
*/
這段程式碼示範了如何用 for
迴圈從 ASCII 表中找出所有的小寫字母,並印出每個字母對應的數值與字元
但講白一點,這不是你每天都會寫的程式。這個範例的重點在於讓你熟悉 for
迴圈的寫法:從一個明確的起點開始(這裡是 char c = 0
),每次檢查是否還在條件內(c < 128
),並做出固定的更新(c++
)
真實世界中,for
迴圈常用來:
- 處理一段固定長度的資料(像是讀入的檔案每一行)
- 重複進行某些特定次數的操作(例如建立 UI 元素、模擬運算、跑 benchmark)
- 在你還沒學會用
foreach
的時候,對陣列內容進行操作
總之,for
迴圈的強項在於「控制感」強,適合你已經知道「要跑幾次」、「從哪開始」和「每次要怎麼走一步」的場合
逗號運算子:多工的小幫手
在 Java 裡,逗號運算子沒什麼存在感,它不像加減乘除那樣常見。但在 for
迴圈的括號內,它有一點小用武之地
你可以在初始化或更新步驟裡,同時處理多個變數。這讓你可以同時追蹤兩件事情,比如一個計數器和一個對應的值,讓你的程式更緊湊,不必寫兩個分開的變數區塊
使用情境?
- 同時追蹤多個變數的關聯變化(像是 i 遞增、j 根據 i 變化)
- 不想把程式拆得七零八落,想要一行裡控制兩件小事
- 在 LeetCode 這種題目裡同時處理兩個索引(雙指標)
不過實務上,除非你有一個明確需要,不然還是建議寫清楚比較容易維護,不要為了帥氣而讓自己三週後看不懂自己在幹嘛
範例
public class CommaOperator {
public static void main(String[] args) {
for(int i = 1, j = i + 10; i < 5; i++, j = i * 2) {
System.out.println("i = " + i + " j = " + j);
}
}
} /* Output:
i = 1 j = 11
i = 2 j = 4
i = 3 j = 6
i = 4 j = 8
*/
在這個例子中,我們設定兩個變數 i
和 j
:
i
是主要的計數器,從 1 開始,直到小於 5。j
則根據i
的值進行更新:一開始是i + 10
,之後每次迴圈執行時變為i * 2
這種寫法的好處是可以在同一個 for
迴圈中同時追蹤並操作兩個有關聯的變數,非常適合用在雙指標法、矩陣對角線掃描或是同時處理兩組資料的時候
這樣做不僅能讓程式碼更濃縮,邏輯也變得更集中。但要注意,可讀性也是工程的一部分,不要寫到連三天後的你自己都看不懂
foreach 迴圈:Java 的懶人迴圈,實際上是日常最常用的武器
如果你只想把一個陣列或清單裡的元素一個個拿出來處理,而不想煩索引那些東西,那 foreach
(也稱 enhanced for loop)會是你的首選
這個語法是在 Java SE5(也就是 Java 1.5)才加入的,是 Java 為了讓開發者能更簡潔地處理集合而新增的語法糖。雖然它還是使用 for
當關鍵字,但這其實是另一種專門用來遍歷陣列和集合的語法,讓你不需要手動寫索引邏輯,直接就能處理每個元素
如果你是從 PHP 來的讀者,這概念就很熟悉。PHP 早就有 foreach ($list as $item)
這種結構了,而 Java 是後來才補上這個開發者友善功能。其他語言會用不同的關鍵字(像 Python 用 for item in list
),但 Java 就是繼續沿用 for
,只是語法變得更輕巧
語法
for (元素類型 變數 : 陣列或集合) {
語句;
}
為什麼你會天天用到它?
幾乎所有日常開發任務都需要「對每個東西做一件事」:
- 處理一個使用者清單中的每個帳號
- 檢查資料庫查詢結果是否符合條件
- 對每個設定檔欄位執行驗證
- 送出每筆訂單通知
以前你可能得寫這種傳統寫法:
for (int i = 0; i < list.length; i++) {
System.out.println(list[i]);
}
用 foreach
可以變成這樣:
for (String item : list) {
System.out.println(item);
}
簡潔、清楚、少出錯
什麼時候不要用?
當你需要知道元素的索引、或是你要在遍歷時修改集合內容(像是新增或移除元素)時,foreach
可能就不太適合。這時候你還是得乖乖用傳統 for
範例
public class ForEachFloat {
public static void main(String[] args) {
Random rand = new Random(47);
float f[] = new float[10];
for(int i = 0; i < 10; i++)
f[i] = rand.nextFloat();
for(float x : f)
System.out.println(x);
}
} /* Output:
0.72711575
0.39982635
0.5309454
0.0534122
0.16020656
0.57799757
0.18847865
0.4170137
0.51660204
0.73734957
*/
在這個範例中,我們透過 foreach
迴圈來處理一個看似日常但非常實用的任務──列出一組隨機浮點數。
- 首先,我們使用 Java 的
Random
類別產生 10 個浮點數,模擬像是從感應器收集的資料、模擬數據、或某種測試用輸入 - 接著使用
foreach
(也就是 enhanced for loop)來遍歷這些數值,逐一列印出來
這種寫法不但簡潔,還能讓你專注在「對每個元素做什麼」這件事,而不是去煩惱索引該怎麼寫,尤其在處理陣列或集合時特別常見。
例如:你讀入了一個 CSV 檔案中的每一列金額,想快速印出來檢查;或是你在測試某個函式的回傳值陣列。這時候,foreach
就是你最直接、最少出錯的選擇
結論
控制流程是每一門程式語言的核心骨架,而 Java 對這部分的設計不只是嚴謹,更是為了讓開發者能寫出清晰、有邏輯的程式
從條件判斷到各種迴圈結構,我們學到的不只是語法本身,而是如何把重複、選擇、邏輯決策這些「程式的大腦」寫進一段段可讀又可控的程式碼中
初學者在學習這些東西時,常常會有「這些結構好像都很簡單,但又不知道實際能做什麼」的困惑。希望這篇文章除了教你語法,也讓你看見這些語法怎麼應用在真實世界:從處理使用者輸入,到遍歷資料清單,甚至建立互動式介面
如果你能掌握這些基本功,未來無論是寫遊戲邏輯、後端 API、還是做資料處理,控制流程都會是你每天都要用到的工具箱──學會怎麼用、用得漂亮,比你背多少語法都重要
Comments ()