MEDIA

メディア

  1. TOP
  2. メディア
  3. プログラミング
  4. Javaのfor文・while文・do-while文を完全比較!使い分けとStream API解説

Javaのfor文・while文・do-while文を完全比較!使い分けとStream API解説

「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重以上にネストすると可読性が著しく低下するため、内側の処理をメソッドとして切り出すなどの工夫が求められます。

ループ制御と無限ループの回避策

ここからは、実務でトラブルになりやすい「無限ループ」の原因と、ループの流れを変えるbreakcontinueの安全な使い方について深掘りします。

無限ループの典型的な原因

まずは、意図しない無限ループが発生する典型的なパターンを見てみましょう。

int i = 0;
while (i < 10) {
    System.out.println(i);
    // ここで i++; を忘れると、iはずっと0のまま
}

このように、while文では「ループ内で変数を更新する処理」を書き忘れると、終了条件が永遠に満たされず無限ループに陥ります。ループを書く際は、「条件式」と「変数の更新」をセットで確認する習慣をつけることが重要です。

breakとcontinueの使い分け

一方で、ループの流れを開発者がコントロールするためにbreakcontinueが用意されています。

  • 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で実務直結の学習を進めてみませんか。

現役エンジニア1on1

コード添削・詰まり解消を丁寧にサポート。

実務設計まで網羅

Java/SQL/Spring Bootを体系的に習得。

ポートフォリオ支援

現場で刺さる成果物づくりを伴走。

完全オンライン

時間と場所を選ばず学べます。

Join us! 未経験からエンジニアに挑戦できる環境で自分の可能性を信じてみよう 採用ページを見る→

記事監修

ドライブライン編集部

[ この記事をシェアする ]

記事一覧へ戻る