Java | 拡張for文(for-each文)

Java Java
スポンサーリンク

まずは要点

拡張 for は「配列やコレクション(List 等)の中身を、順番に1つずつ取り出して処理する」ための簡潔な書き方です。
インデックス(何番目か)を気にせず、要素そのものを扱いたいときに使います。

基本構文:

for (型 変数名 : コレクション) {
    // 変数名 を使った処理
}
Java

例題 1 — 配列の要素を順に表示する(超基本)

String[] names = {"Suzuki", "Sato", "Yamada"};

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

出力:

Suzuki
Sato
Yamada

解説:names 配列の要素が順に name に入って、ブロック内が実行されます。インデックス i を書く必要がないのでコードが短く読みやすいです。


例題 2 — 数値配列の合計を求める

int[] scores = {80, 90, 75, 100};
int sum = 0;

for (int s : scores) {
    sum += s;
}
System.out.println("合計 = " + sum); // 合計 = 345
Java

解説:s が各要素(80, 90, …)を順に受け取り、合計します。配列の長さを別で管理する必要はありません。


例題 3 — ArrayList を使う(コレクションでよく使う)

import java.util.ArrayList;
import java.util.List;

List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");

for (String fruit : list) {
    System.out.println(fruit.toUpperCase());
}
Java

出力:

APPLE
BANANA
CHERRY

解説:配列だけでなく List や他のコレクションにも使えます。


応用例:最大値を見つける

int[] a = {5, 12, 3, 21, 9};
int max = Integer.MIN_VALUE;
for (int v : a) {
    if (v > max) max = v;
}
System.out.println("最大値 = " + max); // 最大値 = 21
Java

多次元配列(2次元配列)の走査

int[][] table = {
    {1, 2, 3},
    {4, 5, 6}
};

for (int[] row : table) {
    for (int value : row) {
        System.out.print(value + " ");
    }
    System.out.println();
}
Java

出力:

1 2 3 
4 5 6 

解説:外側の配列の要素が「行(int[])」で、内側の拡張 for で各行の要素を取り出します。


よくある間違い・注意点(初心者向け)

  • 要素の削除を拡張 for 内でやらない
    コレクション(ArrayList 等)を走査中に list.remove(x) を直接行うと ConcurrentModificationException が出ることがあります。
    → 要素削除は Iterator を使う、または removeIf() を使う、あるいは別のリストに保持して後で削除します。
// 安全な例:removeIf を使う
list.removeIf(f -> f.equals("banana"));
Java
  • インデックスが必要な処理には不向き
    「要素の何番目か」を使う処理(例えば「3番目なら特別処理」)が必要なら、従来の for (int i = 0; i < arr.length; i++) を使います。
  • プリミティブ型とラッパークラスの違い
    List<int> は使えません(List<Integer> を使う)。配列 int[] は問題なく使えます。
  • 走査中に要素を書き換えることはできるが…
    たとえば for (String s : list) の中で s = s.toUpperCase(); としても、list の元の要素は変更されません(s はローカル変数)。要素自体を変更したければインデックスで list.set(i, newValue) を使う必要があります。

実務でよくある使い方(短いテンプレ)

  • 配列/リストの中身を表示
  • 合計・平均を計算
  • 条件でフィルタして別リストへ追加
  • 多次元データの全要素処理

例(フィルタして新しいリストに集める):

List<String> out = new ArrayList<>();
for (String s : list) {
    if (s.startsWith("a")) {
        out.add(s);
    }
}
Java

練習問題(レベル別)+模範解答(ステップ付き)

Easy(基礎)

問題:int[] nums = {2,4,6,8,10}; の各要素を表示しなさい。
解答:

for (int n : nums) {
    System.out.println(n);
}
Java

説明:配列 nums の要素を n に順に入れて出力。

Medium(少し考える)

問題:文字列の配列 {"a","bb","ccc","dd"} から、長さが 2 以上のものだけを表示しなさい。
解答:

String[] arr = {"a","bb","ccc","dd"};
for (String s : arr) {
    if (s.length() >= 2) {
        System.out.println(s);
    }
}
Java

説明:拡張 for で取り出した s に対し length() をチェック。

Hard(応用)

問題:List<Integer> の中から偶数だけを別の List<Integer> にコピーしなさい。(走査中に元リストを破壊しないこと)
解答:

List<Integer> src = List.of(1,2,3,4,5,6); // 不変リストの例
List<Integer> dest = new ArrayList<>();
for (int v : src) {
    if (v % 2 == 0) dest.add(v);
}
System.out.println(dest); // [2,4,6]
Java

説明:拡張 for で要素を順に読み、条件を満たすものを dest に追加。


よくある質問(FAQ)

Q
「拡張 for と従来の for、どっちを使えばいい?」
A

要素をただ順に処理するだけなら拡張 for がシンプル・安全。インデックスが必要、或いは走査中に要素を削除したい/要素をその場で置き換える必要があるときは従来の forIterator を使います。

Q
「拡張 for で要素を変更できる?」
A

変数自体(ループ変数)に新しい値を代入しても元の配列/リストは変わりません。コレクションの要素を更新したいときはインデックスか ListIterator を使ってください。


最後にちょっとしたコツ

  • 読みやすさ最優先:単純な走査は拡張 for
  • 副作用に注意:走査中の削除・置換は例外や意図しないバグに繋がりやすい。
  • 演習で慣れる:配列・ArrayList・2次元配列の練習を何度かやると直感的になります。
タイトルとURLをコピーしました