for (元素型別 變數名 : 陣列或 Iterable) { 循環體 }
int[] nums = {1,2,3,4};
for (int n : nums) System.out.println(n); // 1 2 3 4
編譯器轉換為索引基礎迴圈,零效能損耗。
List list = Arrays.asList("A","B","C");
for (String s : list) System.out.println(s); // A B C
編譯器轉換為 Iterator 迴圈。
in 常用作變數名 (如 System.in),新關鍵字會破壞既有程式碼。for + :。加上 final 修飾符,編譯期禁止對循環變數重新賦值:
for (final int n : nums) { n = n/2; // 編譯錯誤 }
但仍可呼叫方法改變物件內部狀態:
for (final Random r : randoms) { r.setSeed(4); /* 合法 */ }
| 情境 | 範例 | 說明 |
|---|---|---|
| 型別完全相同 | int i : int[] | 最直接 |
| 元素型別為循環變數子型別 | Object o : List<String> | 向上轉型安全 |
| 自動裝箱/拆箱轉換 | Integer i : int[] | JDK 5 Autoboxing 支援 |
注意:Object[] 元素型別固定為 Object,即使實際存放 String。
java.lang.Iterable<T> 介面的類別實例。public interface Iterable {
Iterator iterator();
}
public interface Iterator {
boolean hasNext();
E next();
void remove(); // 選做,拋 UnsupportedOperationException 即可
}
public class TenIntegers implements Iterable {
public Iterator iterator() {
return new Iterator() {
private int count = 0;
public boolean hasNext() { return count < 10; }
public Integer next() { return Integer.valueOf(count++); }
public void remove() { throw new UnsupportedOperationException(); }
};
}
public static void main(String[] args) {
for (int i : new TenIntegers()) System.out.println(i); // 0~9
}
}
利用 Iterable<Integer> + Iterator<Integer> + next() 回傳 Integer,配合 Auto-Unboxing 讓 int 循環變數可用。
Collection 介面繼承 Iterable,故所有 Collection 皆可遍歷。編譯器無特殊對待,任何實作 Iterable 的類別皆可。
iterator() 而非 getIterator():頻繁呼叫,短名稱提升可讀性。hasNext()/next() 而非 hasNextElement()/getNextElement():同理,Collections Framework 設計者刻意簡化。Iterable<T> (不可 implements Iterable<String>, Iterable<Integer>)。stringIterator()) 或統一用 Object。Iterable 實作類。final 防誤修改、泛型精確控制型別、自訂 Iterable 擴展性極佳。