Java for-each 迴圈

for-each 迴圈(增強型 for 迴圈)是遍歷陣列和集合的簡潔方式。

語法

for (型別 變數 : 陣列或集合) {
    // 使用變數
}

遍歷陣列

int[] numbers = {10, 20, 30, 40, 50};

// 傳統 for 迴圈
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

// for-each 迴圈
for (int num : numbers) {
    System.out.println(num);
}

遍歷字串陣列

String[] fruits = {"apple", "banana", "cherry"};

for (String fruit : fruits) {
    System.out.println(fruit);
}
// apple
// banana
// cherry

遍歷集合

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

for (String name : names) {
    System.out.println(name);
}

遍歷二維陣列

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

for (int[] row : matrix) {
    for (int num : row) {
        System.out.print(num + " ");
    }
    System.out.println();
}

for-each vs 傳統 for

優點

  • 程式碼更簡潔
  • 不需要管理索引
  • 不會發生索引越界錯誤

缺點

  • 無法取得當前索引
  • 無法修改陣列元素
  • 無法反向遍歷
  • 無法跳過元素
int[] numbers = {1, 2, 3, 4, 5};

// 無法取得索引
for (int num : numbers) {
    // System.out.println("索引:" + ???);  // 無法取得
}

// 無法修改元素
for (int num : numbers) {
    num = num * 2;  // 這不會改變原陣列
}
System.out.println(Arrays.toString(numbers));  // [1, 2, 3, 4, 5]

// 需要修改時使用傳統 for
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = numbers[i] * 2;
}
System.out.println(Arrays.toString(numbers));  // [2, 4, 6, 8, 10]

何時使用 for-each

情況建議使用
只需讀取元素for-each
需要索引傳統 for
需要修改元素傳統 for
需要反向遍歷傳統 for
需要跳過或刪除元素傳統 for 或 Iterator

實際應用

計算總和

int[] numbers = {10, 20, 30, 40, 50};
int sum = 0;

for (int num : numbers) {
    sum += num;
}

System.out.println("總和:" + sum);  // 150

找出最大值

int[] numbers = {23, 45, 12, 67, 34};
int max = numbers[0];

for (int num : numbers) {
    if (num > max) {
        max = num;
    }
}

System.out.println("最大值:" + max);  // 67

搜尋元素

String[] names = {"Alice", "Bob", "Charlie"};
String target = "Bob";
boolean found = false;

for (String name : names) {
    if (name.equals(target)) {
        found = true;
        break;
    }
}

System.out.println("找到:" + found);  // true

遍歷 Map

Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 85);
scores.put("Bob", 92);
scores.put("Charlie", 78);

// 遍歷 key
for (String name : scores.keySet()) {
    System.out.println(name);
}

// 遍歷 value
for (int score : scores.values()) {
    System.out.println(score);
}

// 遍歷 entry
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

注意事項

不要在遍歷時修改集合

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

// 會拋出 ConcurrentModificationException
// for (String s : list) {
//     list.remove(s);
// }

// 正確方式:使用 Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("b")) {
        it.remove();
    }
}

基本型別的自動裝箱

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 會自動拆箱
for (int num : numbers) {  // Integer -> int
    System.out.println(num);
}