Javaのfor文・while文・do-while文を完全比較!使い分けとStream API解説
CONTENTS
「for文とwhile文、結局どちらを使えばいいのか迷う」「do-while文の実践的な使い道がイメージできない」と悩んでいませんか。
繰り返し処理はプログラミングの基礎ですが、サンプルコードをただ模写しているだけでは、無限ループによるシステムダウンや、可読性の低いコードを生む原因になりがちです。
そのため、本記事ではJavaの代表的な3つのループ構文の明確な使い分けから、拡張for文、多重ループ、そしてJava 8以降のスタンダードであるStream APIによる「ループを書かない技術」までを体系的に解説します。
一方で、プログラミング言語のトレンドは変化していますが、ループ制御の基礎となる考え方は2025年現在でも変わりません。ここで確実な基礎体力を身につけ、迷いのないコーディングを目指しましょう。
Javaのループ構文3種類と選び方の基準
まずは、Javaで頻繁に使用される3つのループ構文(for・while・do-while)の特徴と、実務における選び方の基準を整理します。
一般的に、ループ処理を選ぶ際は「繰り返す回数が決まっているか」、あるいは「外部の状態によって回数が変動するか」という観点で判断します。それぞれの特徴を以下の表にまとめました。
| 構文 | 主な用途・特徴 | 適している場面 |
|---|---|---|
| for文 | 回数指定、インデックス操作 | 配列の全要素処理、回数が明確な計算 |
| while文 | 条件指定(前判定) | ファイル読み込み、ユーザー入力待機 |
| do-while文 | 実行保証付き条件指定(後判定) | 最低1回は実行したいメニュー表示など |
このように、配列やリストを順に処理したい場合はfor文が適しており、条件が満たされるまで繰り返したい処理にはwhile文などが向いています。適切な構文を選ぶことは、バグを防ぐ第一歩です。
さらに詳しい仕様については、Oracle公式ドキュメントも併せて参照してください。
Oracle公式:The for Statement
for文:回数が決まっている処理の王道
まずは、最も基本的かつ頻出するfor文から確認していきましょう。
for (int i = 0; i < length; i++) {
System.out.println("現在のインデックス: " + i);
}
具体的には、for文は「初期化」「条件式」「更新処理」を1行に集約して記述できる点が最大のメリットです。「0からスタートしてlength未満まで」「1ずつ増やす」といったロジックが一目で分かるため、可読性が高く維持できます。
while文:条件のみで制御するループ
一方で、while文は「条件がtrueである限り繰り返す」というシンプルな構造を持ちます。
int count = 0;
while (count < max) {
// 処理を実行
process(count);
// 終了条件へ近づける更新が必要
count++;
}
このように、while文は「いつ終わるか」を条件式として定義します。したがって、データベースからレコードを1行ずつ読み込む処理や、正しい入力が得られるまで待機する処理など、回数が事前には不明なケースと相性が良いです。
do-while文:必ず1回は実行するループ
さらに、do-while文は「処理を実行してから条件判定を行う」という特徴があります。
int input;
do {
System.out.println("数値を入力してください(負の数で終了):");
input = scanner.nextInt();
} while (input >= 0);
例えば、CLIツールでのメニュー表示やユーザー入力の受付など、「とにかく一度は処理を通したい」場面で有効です。while文では条件がいきなりfalseの場合に一度も実行されませんが、do-while文ならその心配がありません。
詳細な仕様比較は、以下のドキュメントも参考になります。
Oracle公式:The while and do-while Statements
拡張for文と多重ループの実践テクニック
次に、配列やコレクション(List, Setなど)を効率的に扱うための構文や、複雑なデータ構造を処理する多重ループについて解説します。
拡張for文(for-each)のメリットと注意点
Java 5で導入された拡張for文は、コレクションの全要素を順番に取り出す処理に特化しています。
List names = List.of("Tanaka", "Sato", "Suzuki");
for (String name : names) {
System.out.println(name);
}
具体的には、インデックス管理(i++など)が不要になるため、記述ミスによるバグを減らせるのが大きな利点です。単にデータを読み取って表示・計算するだけなら、最も推奨される書き方です。
しかし、ループ中に要素を削除(remove)しようとすると、ConcurrentModificationExceptionという例外が発生する場合があります。そのため、ループ内で要素数を変更する必要がある場合は、従来のfor文やIteratorを使用するようにしましょう。
多重ループによる表形式データの処理
さらに、表形式のデータや多次元配列を扱う際には、ループを入れ子にする「多重ループ」が登場します。
int[][] table = new int[9][9];
// 行(縦)のループ
for (int i = 1; i <= 9; i++) {
// 列(横)のループ
for (int j = 1; j <= 9; j++) {
table[i - 1][j - 1] = i * j;
}
}
例えば九九の表を作る場合、外側のループを行、内側のループを列として捉えると構造が理解しやすくなります。ただし、ループが3重以上にネストすると可読性が著しく低下するため、内側の処理をメソッドとして切り出すなどの工夫が求められます。
ループ制御と無限ループの回避策
ここからは、実務でトラブルになりやすい「無限ループ」の原因と、ループの流れを変えるbreakやcontinueの安全な使い方について深掘りします。
無限ループの典型的な原因
まずは、意図しない無限ループが発生する典型的なパターンを見てみましょう。
int i = 0;
while (i < 10) {
System.out.println(i);
// ここで i++; を忘れると、iはずっと0のまま
}
このように、while文では「ループ内で変数を更新する処理」を書き忘れると、終了条件が永遠に満たされず無限ループに陥ります。ループを書く際は、「条件式」と「変数の更新」をセットで確認する習慣をつけることが重要です。
breakとcontinueの使い分け
一方で、ループの流れを開発者がコントロールするためにbreakとcontinueが用意されています。
- break:ループを即座に中断して脱出する。
- continue:現在の周の処理をスキップし、次の周へ進む。
while (true) {
String input = scanner.nextLine();
// "exit"が入力されたらループを抜ける
if ("exit".equals(input)) {
break;
}
// 入力が空なら処理をスキップして次の入力を待つ
if (input.isEmpty()) {
continue;
}
processInput(input);
}
具体的には、上記のような常駐型の処理や入力チェックで頻繁に使用されます。ただし、これらを多用しすぎると処理の流れが追いにくくなるため、「メソッドを分割してreturnで終了させる」といった代替案も検討すべきです。
Stream API:ループを書かない現代的な記述
最後に、Java 8以降で標準となったStream APIを用いたアプローチを紹介します。これは従来のループ構文とは異なり、「何をしたいか」を宣言的に記述するスタイルです。
List numbers = List.of(1, 2, 3, 4, 5);
// 偶数だけを抽出して、2倍にして、合計する
int sum = numbers.stream()
.filter(n -> n % 2 == 0) // フィルタリング
.mapToInt(n -> n * 2) // 変換
.sum(); // 集計
このように、Stream APIを使うと、for文のようなインデックス管理や一時変数(合計値用の変数など)が不要になります。その結果、コードの意図が明確になり、バグの混入を防ぐ効果も期待できます。
しかし、処理の途中で複雑な分岐が入る場合や、デバッグのしやすさを優先する場合は、従来のfor文の方が適していることもあります。したがって、「単純な集計・変換はStream」「複雑な制御はループ」と使い分けるのが現場のベストプラクティスです。
Stream APIのより詳細な機能については、以下の公式リファレンスが役立ちます。
Oracle公式:Stream (Java Platform SE 8 )
まとめ:ループ構文を使いこなして脱初心者へ

本記事では、Javaのループ構文の基礎から、実務的な使い分け、そしてモダンなStream APIまでを解説しました。ポイントを振り返ります。
- for文:回数が決まっている処理や配列操作に最適。
- while文:終了条件のみが決まっている不安定な処理に向く。
- 拡張for文:コレクション処理の基本だが、要素削除には注意。
- Stream API:集計や変換をシンプルに書ける現代の標準。
これらを適切に使い分けることで、バグが少なく、誰が見ても理解しやすいコードを書けるようになります。まずは基本的なfor文と拡張for文をマスターし、徐々にStream APIによる効率化にも挑戦してみてください。
つまずいたら、現役エンジニアと一緒に解決しよう
この記事で扱った【Java】は、独学だと細部で詰まりやすい分野です。さらに理解を深めたい方は、Zerocode Onlineで実務直結の学習を進めてみませんか。
コード添削・詰まり解消を丁寧にサポート。
Java/SQL/Spring Bootを体系的に習得。
現場で刺さる成果物づくりを伴走。
時間と場所を選ばず学べます。