Java 5 引入的增強 for 循環(Enhanced for Loop),又稱「for-each 循環」,是遍歷數組與 Iterable 集合的語法糖。它將「獲取迭代器 → 判斷有無下一個 → 取值」的樣板代碼封裝為簡潔的聲明式語法,極大提升了代碼可讀性。
// 數組遍歷
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println(num);
}
// List/Set 遍歷
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
// Map 遍歷(需配合 keySet/entrySet)
Map<String, Integer> scores = Map.of("Math", 95, "English", 88);
for (String subject : scores.keySet()) {
System.out.println(subject + " = " + scores.get(subject));
}
// 推薦:Map 直接遍歷 Entry 避免二次查找
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
增強 for 循環純屬編譯期語法糖,javac 會將其還原為基於索引或迭代器的普通循環。以數組為例:
// 源碼
for (int num : numbers) { ... }
// 編譯後等效字節碼邏輯
int[] arr = numbers;
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
...
}
對於 Iterable 集合,則轉換為迭代器模式:
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
...
}
結論:增強 for 無運行時性能損耗,純粹是編譯器幫你寫樣板代碼。
| 限制 | 說明 | 替代方案 |
|---|---|---|
| 無法獲取索引 | 遍歷數組/List 時拿不到下標 | 改用普通 for 或 IntStream.range |
| 無法反向/跳躍遍歷 | 只能從頭到尾、步長為 1 | 普通 for / ListIterator / Stream API |
| 無法安全刪除元素 | 循環中直接 list.remove() 拋 ConcurrentModificationException | 用 Iterator.remove() 或 Stream filter |
| 無法修改數組/集合結構 | 無法在遍歷中添加元素 | 收集需操作的元素,循環外統一處理 |
Map 未實現 Iterable,不能直接用增強 for。三種常見姿勢:
for (K key : map.keySet())for (V val : map.values())for (Map.Entry<K,V> e : map.entrySet())對於複雜業務邏輯(篩選、轉換、聚合),Stream API 往往更優雅:
// 篩選分數 > 90 的科目並轉大寫輸出
scores.entrySet().stream()
.filter(e -> e.getValue() > 90)
.map(Map.Entry::getKey)
.map(String::toUpperCase)
.forEach(System.out::println);
增強 for 循環是 Java 遍歷集合的「標準動作」,代碼簡潔、語義清晰、零性能損耗。但面對「需要索引、逆序、刪除、複雜邏輯」等場景時,果斷切換到普通 for、Iterator 或 Stream API,才是成熟工程師的選擇。