はじめに
Javaの拡張for文は、配列やListなどの要素を先頭から順に取り出す構文です。インデックスを直接扱わないため、プログラミング入門でも読みやすい反復処理を書けます。
ただし、要素の削除、添字が必要な処理、例外、forEachやラムダ式との使い分けには注意が必要です。Java基本文法として形だけでなく、通常のfor文へ切り替える場面まで整理すると、プログラミング学習の理解が安定します。
- Java 21
- OpenJDK 21 / javac 21
- 拡張for文の構文と通常のfor文との違い
- 配列、List、二次元配列での実用的な書き方
- 条件分岐、メソッド、独自クラスとの組み合わせ
- 削除処理や添字が必要な場面での判断基準
- ラムダ式やforEachとの使い分け
拡張for文の基本
拡張for文は「全要素を順番に読む」処理に向いたJava基本文法です。最小形はfor (型 変数 : 配列またはIterable)で、右側のデータから要素を取り出し、左側の変数へ順に代入します。
結果: 期待される出力は、1、2、3が行ごとに表示される形です。
numberはループごとに現在の要素を受け取ります。iの初期化、i < numbers.lengthの条件、i++の更新式は不要です。
公式ドキュメントによれば、拡張for文は配列とIterableを実装したオブジェクトに使えるのが基本です。構文の根拠はJava Language Specification 14.14.2で確認できるのが基本です。
ただし、拡張for文は現在の添字を直接持ちません。添字を使う処理は通常のfor文、要素だけで完結する処理は拡張for文と分けると、コーディングテクニックとして判断しやすくなります。
定義と特徴
拡張for文は、enhanced for statementやfor-each loopとも呼ばれますし、ここがポイントです。Javaではforキーワードを使いますが、通常のfor (初期化; 条件; 更新)とは構造が異なります。
配列の全件表示、リスト内の集計、文字列リストのチェックでは、添字より要素そのものに関心があるのが目安です。String item : itemsなら「itemsの各要素をitemとして扱う」と読み取れますが、これは押さえたい点です。
breakやcontinueは通常のループと同じように使えます。条件に合う要素で止める、特定の値だけ飛ばす処理も書けます。
💡 Tips: プログラミング入門では、配列の全要素を読む処理を拡張for文で書き、添字が必要になった時点で通常のfor文へ戻す考え方が扱いやすいです。
基本的な構文
基本構文では、左側に要素の型と変数名、右側に配列やコレクションを書きますし、これが一つの目安です。左側の型は、右側から取り出される要素の型と一致させますし、ここがポイントです。
結果: 構文のひな形であり、右側のデータから取り出した要素を左側の変数で扱う形になります。
int[]ならint number、String[]ならString text、List<String>ならString valueのようにそろえますが、覚えておくと役立つでしょう。型が合わない場合はjavacのコンパイル時点でエラーになります。
Java基本文法の学習では、右側の要素型を先に読む習慣が役立ちますが、これは押さえたい点です。サンプルコードも、forの右側から左側へ視線を移すと構造を追いやすくなるのが目安です。
| 項目 | 書き方 | 向く場面 | 注意点 | 関連する語 |
|---|---|---|---|---|
| 配列の全件表示 | for (int n : numbers) | 全要素を読む | 添字は取れない | 拡張for文 |
| 文字列配列 | for (String s : names) | 文字列を順に処理 | null要素に注意 | Java基本文法 |
| List | for (String item : list) | 順序付きの要素処理 | 削除は避ける | プログラミング入門 |
| Set | for (String tag : tags) | 重複なし集合 | 順序は実装依存 | コーディングテクニック |
| 二次元配列 | for (int[] row : matrix) | 行単位の走査 | 内側のループが必要 | サンプルコード |
| 条件分岐 | if (n % 2 == 0) | 条件に合う要素だけ処理 | 条件を複雑にしすぎない | プログラミング学習 |
| 途中終了 | break | 目的の値を見つけた時点で終了 | 終了条件を明確にする | 制御構文 |
| スキップ | continue | 特定要素を飛ばす | 読みづらい多用を避ける | 分岐 |
| 集計 | sum += n | 合計や件数の計算 | 初期値を確認する | 変数 |
| 最大値探索 | max = Math.max(max, n) | 値の比較 | 空配列の扱いが必要 | Math.max |
| メソッド呼び出し | print(item) | 処理を分ける | 副作用を確認する | メソッド |
| 独自クラス | for (Person p : people) | オブジェクト配列 | getterの設計に注意 | class |
| ラムダ式 | list.forEach(x -> ...) | 短い処理 | 複雑な処理は読みにくい | forEach |
| 削除処理 | Iterator | 反復中に削除 | removeを使う | Iterator |
| 添字が必要 | for (int i = 0; ...) | 番号付き処理 | 境界条件に注意 | length |
| 配列長 | array.length | 通常for文 | メソッドではない | length |
| Listサイズ | list.size() | 通常for文 | メソッド呼び出し | size() |
| 標準出力 | System.out.println | 学習用の確認 | 業務ログとは分ける | System.out |
| 文字数 | text.length() | 文字列処理 | 文字単位の意味に注意 | String |
| 例外処理 | try/catch | 失敗に備える | 広すぎる捕捉を避ける | Exception |
| null対策 | if (x != null) | null要素の確認 | 呼び出し前に判定 | null |
| 型推論 | var | 型が明白な場面 | 読みやすさを優先 | var |
| final変数 | final String name | 再代入を避ける | 要素自体の不変ではない | final |
| Map | entrySet() | キーと値の走査 | Entry型を読む | Map.Entry |
| Stream | stream() | 変換や絞り込み | 副作用を減らす | Stream |
| 配列変換 | Arrays.asList | 簡単なリスト化 | 固定サイズの性質に注意 | Arrays |
| 空判定 | isEmpty() | 処理前チェック | nullとは別 | isEmpty |
| ネスト | forの中にfor | 表形式データ | 深くしすぎない | 二重ループ |
| 可読性 | 短い変数名を避ける | チーム開発 | 意味のある名前にする | 命名 |
| 学習順 | 配列からListへ進む | プログラミング学習 | 構文と用途を分ける | プログラミング入門 |
早見表では、サンプルコードで頻出する形と注意点をまとめています。対象がarrayかCollectionかで周辺の書き方は変わります。
Java List型完全ガイドを併読すると、Listと拡張for文の関係を整理できるのがポイントです。配列だけでなくコレクションまで扱うと、Java基本文法の理解が深まりますし、これが一つの目安です。
拡張for文の使い方
拡張for文の使い方は配列から始めると理解しやすいです。String[]やint[]は要素の型と個数が明確で、プログラミング入門の教材にもよく登場します。
サンプルコード1:基本的な使い方
文字列配列を作り、各要素をSystem.out.printlnで表示する形が最小のサンプルコードです。変数fruitは、配列fruitsの要素を順番に受け取りますし、ここを基本と考えるとよいでしょう。
結果: 期待される出力は、りんご、みかん、ぶどうがこの順番で行ごとに表示される形です。
String[]の要素型はStringなので、ループ変数もString fruitになります。ループ内ではfruit.length()のようなStringのメソッドも呼び出せます。
ループ変数へ別の文字列を代入しても、配列そのものの要素は置き換わりません。要素の値や参照を受け取って処理する構文です。
サンプルコード2:配列との組み合わせ
配列との組み合わせでは、数値の合計や平均の計算にも拡張for文を使えるのが一般的です。読み取り専用の集計なら、添字を持たないことが意図の明確さにつながりますが、覚えておくと役立つでしょう。
結果: 期待される出力は合計: 345です。
このサンプルコードでは、totalに各scoreを足し込みます。scores[0]のような添字表現がないため、全件を足す処理だと読み取れます。
偶数番目だけ処理する、前後の要素を比較する、表示番号を付ける要件では添字が必要です。その場合はfor (int i = 0; i < scores.length; i++)へ切り替えますし、ここがポイントです。
サンプルコード3:コレクションとの組み合わせ
コレクションでは、ArrayListをList型の変数で受ける書き方がよく使われますし、ここを基本と考えるとよいでしょう。java.util.Listの詳細はJava SE 21 APIのListで確認できます。
結果: 期待される出力は、りんご、バナナ、ぶどうが追加した順番で行ごとに表示される形です。
ArrayListは追加順を保持するため、出力も追加順になります。HashSetのような集合では順序が保証されず、同じ拡張for文でも表示順の意味が変わります。
順序に意味がある処理ではList、重複を避ける処理ではSetのように選びますが、これは押さえたい点です。これは拡張for文ではなく、データ構造を選ぶコーディングテクニックです。
Listの基本を先に固めたい場合は、本文中の内部リンクから関連するJava記事へ進むと、プログラミング学習の流れを崩さず確認できるのがポイントです。Javaエスケープ処理のガイドでは、文字列を扱う際のnや"の考え方を確認できます。文字列配列を出力するサンプルコードにも役立ちますし、これが一つの目安です。
拡張for文の応用例
拡張for文に慣れたら、二次元配列、条件分岐、メソッド呼び出しへ広げると実用に近づきます。単純な表示から処理の分割へ進むことで、Java基本文法が部品としてつながりますし、ここがポイントです。
サンプルコード4:ネストされた拡張for文
二次元配列は「配列の中に配列がある」構造です。外側の拡張for文で行を取り出し、内側の拡張for文で行の中の値を取り出するのが現実的です。
結果: 期待される出力は、1 2 3、4 5 6、7 8 9が行ごとに表示される形です。
rowの型はint[]で、elementの型はintです。外側と内側で型が変わる点を読むと、二重ループの意味を追いやすくなります。
ネストが深くなるほど読み手の負担は増えます。三重以上のループでは、メソッドへの切り出し、データ構造の見直し、Streamの利用も検討すると整理できるのが一般的です。
サンプルコード5:条件分岐との組み合わせ
条件分岐と組み合わせると、全要素を読みながら条件に合うものだけ処理できます。整数配列から偶数だけを出力する処理では、%演算子で割り切れるかを判定します。
結果: 期待される出力は、2は偶数です、4は偶数です、6は偶数ですが行ごとに表示される形です。
この例では、奇数のときにcontinueで残りの処理を飛ばします。条件に合わない要素を早めに除外すると、出力処理の条件が読みやすくなります。
条件が何層にも重なる場合は、isEven(number)のような判定メソッドを作ると扱いやすくなると理解できるのが現実的です。プログラミング学習では、長いifを短い名前付きメソッドへ分ける考え方も重要です。
サンプルコード6:メソッドとの組み合わせ
メソッドと組み合わせると、ループの役割を「要素を渡すこと」に絞れます。表示や計算の詳細は別メソッドへ移すため、拡張for文の中身が短くなります。
結果: 期待される出力は、各フルーツ名とlength()で得られる文字数が交互に表示される形です。
このサンプルコードでは、printFruitDetailsが一つのStringを受け取り、名前と文字数を表示します。拡張for文は配列の各要素を順に渡すだけです。
同じ処理を別の配列やListにも使いたい場合、メソッド化が有効です。単なる短縮ではなく、コーディングテクニックとして再利用の単位を作る作業です。
Javaのオーバーライド解説を読むと、メソッド名、引数、戻り値の考え方を広げられます。拡張for文から呼ぶメソッドの設計にもつながりますが、覚えておくと役立つでしょう。
拡張for文の詳細な注意点
拡張for文は読みやすい反復処理を書けますが、すべてのループを置き換える構文ではありません。特に、例外、要素の削除、添字、性能の見方は押さえる必要があると整理できます。
例外処理の取り扱い
拡張for文自体は、配列の範囲外へ添字アクセスする構文ではありません。for (int value : array)で読むだけなら、添字ミスによるArrayIndexOutOfBoundsExceptionは起きにくくなります。
ただし、ループ内で別の配列へ添字アクセスしたり、null要素に対してメソッドを呼んだりすれば例外は発生すると覚えるとよいでしょう。拡張for文は例外を消すのではなく、添字管理の一部を不要にします。
結果: 期待される出力は、2、名前が未設定です、2が行ごとに表示される形です。
このコードでは、name == nullを先に判定してからlength()を呼び出します。つまずきやすい点は構文ではなく、ループ内で扱う値の状態です。
公式ドキュメントによれば、NullPointerExceptionはnull参照に対してインスタンスメソッドを呼ぶ場合などに発生します。詳細はJava SE 21 APIのNullPointerExceptionが一次情報です。
要素の削除とConcurrentModificationException
拡張for文でListを回している最中に、同じListから直接removeすると、ConcurrentModificationExceptionが起きる場合があります。反復中の構造変更は慎重に扱います。
list.remove(item)を直接呼ぶ書き方は避けますし、ここを基本と考えるとよいでしょう。削除が必要な場合はIteratorのremove()、またはremoveIfを検討すると覚えるとよいでしょう。結果: 期待される出力は[田中, 佐藤]です。
この例では、削除が必要なため拡張for文ではなくIteratorを使っています。読み取り中心なら拡張for文、反復中に安全に削除したいならIteratorが一般的です。
条件に合う要素をまとめて消すだけなら、removeIfも候補です。短い条件ならnames.removeIf(name -> name.equals("未設定"))のように書けます。
パフォーマンスに関する注意
性能については、拡張for文が常に遅い、または常に速いとは言えません。配列では添字ベースのループに近い形、コレクションでは通常Iteratorを介した反復になると考えられますが、これは押さえたい点です。
短い確認コードは、JITコンパイル、ウォームアップ、最適化、実行環境の影響を受けます。学習用のサンプルコードだけで速度の優劣を断定するのは避けます。
結果: 期待される出力は、田中、佐藤、鈴木が行ごとに表示される形です。
この程度の処理では、可読性を優先して拡張for文を選ぶ判断が自然です。性能差が問題になるのは、大量データや処理時間の制約が明確な箇所に限られます。
読みやすい拡張for文を基本にし、添字アクセスが必要な箇所だけ通常のfor文にする書き分けが実用的です。プログラミング入門から実務寄りのプログラミング学習へ進む際にも役立ちます。
拡張for文のカスタマイズ方法
拡張for文の対象は、プリミティブ配列や文字列リストだけではありません。独自クラスの配列、List<Person>、Map.Entry、ラムダ式を使ったforEachにも広げられますし、ここがポイントです。
サンプルコード7:カスタムクラスの利用
独自クラスを配列に入れると、拡張for文でオブジェクトを一件ずつ取り出せますし、これが一つの目安です。Personクラスにnameとageを持たせ、配列として扱う形です。
結果: 期待される出力は、田中さんは30歳です、佐藤さんは25歳です、鈴木さんは35歳ですが行ごとに表示される形です。
Personのフィールドはprivate finalで、値の取得はgetName()とgetAge()に任せています。拡張for文はPersonオブジェクトを順に受け取り、必要なメソッドを呼びます。
クラス設計が複雑になるほど、ループ内に処理を書き込みすぎると読みにくくなると言えるでしょう。表示用の文字列をtoDisplayText()のようなメソッドへ寄せると、コーディングテクニックとして責任範囲を分けられますが、覚えておくと役立つでしょう。
Mapのキーと値を扱う
Mapでは、entrySet()でMap.Entryを取り出す形がよく使われます。キーと値を同時に使いたいときに向いた書き方です。
結果: 期待される出力は、田中: 80、佐藤: 90、鈴木: 75が行ごとに表示される形です。
この例では、追加順を保つためにLinkedHashMapを使っています。HashMapでは順序に依存しない処理にする必要があります。
Javaアノテーションの解説では、クラスやメソッドへメタ情報を付ける考え方を確認できるのが基本です。独自クラスを扱うプログラミング学習では、文法同士のつながりも重要です。
サンプルコード8:ラムダ式との組み合わせ
Java 8以降では、forEachとラムダ式で各要素を処理する書き方も使えると理解できます。拡張for文そのものではありませんが、各要素に処理を適用する場面で比較されます。
結果: 期待される出力は、apple、banana、cherryが行ごとに表示される形です。
item -> System.out.println(item)が各要素への処理を表します。短い出力や単純な変換には向きますが、breakやcontinueは拡張for文と同じ感覚では使えません。
途中で抜けたい、例外処理を細かく書きたい、複数行の条件分岐がある場合は拡張for文が扱いやすいことがあります。短さだけでなく、制御の明確さで選びますが、これは押さえたい点です。
Javaでうるう年を判定する記事のような条件分岐中心の例も参考になります。条件を小さく名前付きにする考え方は、ラムダ式でも拡張for文でも共通するのが目安です。
まとめ
拡張for文は、配列やコレクションの全要素を順に読む処理に向いたJava基本文法です。for (String item : items)の形にすると、要素を一件ずつ処理する意図が短く伝わります。
添字が必要な処理、反復中の削除、途中終了を細かく制御する処理では、通常のfor文やIteratorが適する場合があると考えられます。構文の短さだけでなく、処理の目的に合わせて選びますし、これが一つの目安です。
プログラミング入門では、配列の表示、合計、条件分岐、メソッド呼び出しの順にサンプルコードを写すと使いどころをつかみやすくなります。プログラミング学習では、同じ処理を通常のfor文でも書き比べると違いが見えます。
拡張for文は「要素を読む」ための構文であり、「場所を操作する」構文ではありません。この違いを覚えると、List、Map、ラムダ式へ進んだときも判断しやすくなるのがポイントです。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


