| 維度 | for 循環 | while 循環 | do-while 循環 |
|---|---|---|---|
| 判斷時機 | 每次迭代前 | 每次迭代前 | 每次迭代後 |
| 最少執行次數 | 0 次 | 0 次 | 1 次 (先執行體,後判斷) |
| 語法結構 | for(初始化; 條件; 更新) {體} | while(條件) {體} | do {體} while(條件); |
| 變量作用域 | 初始化變量僅循環內可見 | 外部定義,循環後仍可見 | 外部定義,循環後仍可見 |
| 典型適用場景 | 已知次數、計數器、遍歷 | 未知次數、條件驅動、流讀取 | 菜單交互、輸入驗證、至少一次處理 |
// for 循環
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
// while 循環
int sum = 0, i = 1;
while (i <= 100) {
sum += i;
i++;
}
// do-while 循環
int sum = 0, i = 1;
do {
sum += i;
i++;
} while (i <= 100);
// while: 可能零次執行 (首次輸入即 exit)
Scanner sc = new Scanner(System.in);
String input;
while (!(input = sc.nextLine()).equals("exit")) {
System.out.println("收到: " + input);
}
// do-while: 保證至少提示一次
do {
System.out.print("請輸入: ");
input = sc.nextLine();
if (!input.equals("exit")) System.out.println("收到: " + input);
} while (!input.equals("exit"));
// 僅用於遍歷集合/數組,無索引、不可修改結構
List list = Arrays.asList("A", "B", "C");
for (String s : list) {
System.out.println(s);
}
// 編譯器轉為 Iterator (集合) 或 索引訪問 (數組)
// 非 RandomAccess 集合 (LinkedList) 效率等同手寫 Iterator
break:立即退出最近一層循環continue:跳過本次迭代剩餘,進入下一次判斷label::配合 break/continue 控制外層循環// 雙層循環查找
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 2) {
System.out.println("Found at " + i + "," + j);
break outer; // 直接跳出雙層
}
}
}
需要索引/計數器? ├─ 是 → for (int i=0; i常見錯誤
- 邊界錯誤:
i <= size()→ 越界,正確i < size()- 循環中修改集合:拋
ConcurrentModificationException→ 用 Iterator.remove()/removeIf()- 死循環:
while(true)缺 break → CPU 100%- 浮點判斷:
for(double d=0; d!=1.0; d+=0.1)可能永不結束 → 用整數計數總結
for、while、do-while 核心區別在於判斷時機 (前/後)與最少執行次數 (0/1)。語義選擇:已知次數 for、條件驅動 while、至少一次 do-while、遍歷 for-each、複雜管道 Stream。性能無本質差異,JIT 自動優化。避開邊界、集合修改、死循環、浮點判斷四大常見陷阱。