読み込み中...

Javaでマスターするたった8つのwhile文ループテクニック

Javaのwhile文徹底解説 Java
この記事は約29分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

Javaのwhile文は、条件が成り立つ間だけ処理を繰り返すループ構文です。回数がはっきり決まる処理にはfor文が合いやすい一方、入力、ファイル読み込み、外部状態の変化など、終了タイミングが処理中に決まる場面ではwhileの使い方が役立ちます。

初心者がつまずきやすいのは、条件式の更新忘れ、breakcontinueの違い、無限ループの止め方です。そのため、サンプルコードごとに初期値、条件式、更新処理、終了条件を分けて読むと、Javaプログラミングで必要な反復処理を整理しやすくなります。

動作確認環境
  • Java SE 21 / JDK 21
  • 標準ライブラリ: java.base, java.util, java.io
  • コマンドライン実行を想定: javac / java
📖 この記事で学べること
  • Javaのwhile文でループを作る基本構造
  • カウンター、複数条件、無限ループの扱い方
  • for文やdo-while文との使い分け
  • 配列、入力、ファイル、リストで使うサンプルコード
  • 無限ループやCPU負荷に関する注意点

Javaとは

Javaは、クラスを中心にプログラムを組み立てるオブジェクト指向のプログラミング言語です。一般に、Webアプリケーション、Android関連開発、業務システム、学習用のアルゴリズム演習などで使われ、同じ文法で複数の環境に対応しやすい特徴があります。

公式ドキュメントによれば、制御文にはifswitchwhileforなどが含まれます。条件によって処理を分岐し、必要な間だけループを続ける仕組みを理解すると、初心者でも小さなプログラムから段階的に読み書きしやすくなるのが基本です。

学習を進める際は、基本構文と標準ライブラリの両方を参照すると理解が安定します。制御文の仕様はOracle Java Tutorialsのwhile文解説、入力処理はJava SE 21のScanner APIで確認できます。

基本的に、学習では小さなクラスを作ってコンパイルし、出力を確認する流れから始めますし、ここがポイントです。while文のような制御構文も同じで、最初は一つの変数だけを動かし、条件式がどのタイミングで変わるかを追うと理解しやすくなります。

基本構文

最小構成は、classの中にmainメソッドを置き、そこから処理を始める形です。publicstaticvoidString[] argsは最初に覚える記述で、コンソール出力にはSystem.out.printlnを使います。

// クラスの定義
public class HelloWorld {
  // メインメソッド
  public static void main(String[] args) {
    // 処理内容
    System.out.println("Hello, world!");
  }
}

結果: 期待される出力はHello, world!です。

このサンプルコードでは、HelloWorldクラスの中にmainメソッドを定義しているのが目安です。その中のSystem.out.println("Hello, world!");が文字列を出力する行で、Javaプログラミングの入口として読みやすい構成です。

その構造を押さえたら、mainメソッドの中に変数、条件分岐、ループを追加していきます。関連する基礎型の整理にはJava List型完全ガイドも合わせて参照できます。

ちなみに、学習用であればIDEを先に整えるより、ターミナルでjavac HelloWorld.javajava HelloWorldを動かす流れを一度確認すると、コンパイルと実行の違いを把握できるのがポイントです。IDEの実行ボタンも内部では同じ考え方でクラスを読み込み、mainメソッドを起点に処理を開始します。

インストール方法

開発環境を整えるには、JDKをインストールしてjavacjavaコマンドを使える状態にします。Oracle JDKやOpenJDK系ディストリビューションを選び、Windows、macOS、Linuxの環境に合わせてPATHを設定する流れになるのが一般的です。

具体的には、JDKをダウンロードし、インストーラまたはパッケージ管理ツールで導入し、ターミナルでjava -versionを確認します。この確認でバージョンが表示されれば、.javaファイルをコンパイルして実行する準備が整います。

💡 Tips: 初心者は、学習用フォルダを一つ作り、クラス名とファイル名を一致させる運用から始めると混乱しにくくなるのが現実的です。

while文の基本

while文は、条件式がtrueである間だけ処理を繰り返すJavaのループ構文です。最初に条件を判定するため、条件が最初からfalseならループ本体は一度も動きません。

そのため、while文を読むときは、初期値、条件式、更新処理の位置を確認します。初心者向けの使い方では、この三つが離れて書かれる点を意識すると、無限ループの注意点にも気づきやすくなります。

構文判定位置向く処理主な注意点代表例
while先頭終了条件が変動する処理更新忘れで止まらない入力待ち、EOFまで読み込み
for先頭回数が明確な処理条件が複雑だと読みにくい配列の全件走査
do-while末尾最低一度は動かす処理末尾の;を忘れやすいメニュー入力
break任意途中終了終了条件が散らばる検索成功時の停止
continue任意一部処理のスキップ更新位置に注意条件に合わない行の除外

これにより、while文は「状態が変化するまで待つ」処理を自然に表せます。たとえば、入力値が特定の文字列になるまで待つ、ファイルの末尾に達するまで読む、キューが空になるまで取り出す、といった処理では終了回数より終了条件が主役になります。

構造と機能

while文の基本形は、丸かっこの中に条件式を置き、波かっこの中に繰り返したい処理を書きますが、これは押さえたい点です。条件式にはi < 10のような比較式、hasNextのような真偽値、&&||を組み合わせた式を使えます。

while (条件式) {
  // ループ内で実行する処理
}

結果: 条件式がtrueである間、波かっこ内の処理が繰り返される構造になります。

この構造では、ループ内で条件に関わる値を変化させる設計が必要です。たとえばint i = 0で始め、処理の最後でi++を実行すると、いつかi < 10falseになって停止すると整理できます。

このとき、条件式を読む順番は「現在の値で判定し、処理し、値を変える」です。i++を出力の前に置くと表示される値が1つずれるため、同じwhile文でも更新位置によって期待される出力が変わります。

サンプルコード1:基本的なwhile文

最初のサンプルコードは、整数iを0から9まで増やす単純なループです。条件、出力、更新の順に読むと、while文の動きが追いやすくなります。

public class BasicWhileExample {
  public static void main(String[] args) {
    int i = 0; // 初期値
    while (i < 10) { // 条件式
      System.out.println("現在のiの値は " + i);
      i++; // iを1増加させる
    }
  }
}

結果: 期待される出力は現在のiの値は 0から現在のiの値は 9までです。

このコードでは、i < 10が成り立つ間だけSystem.out.printlnが実行されます。その後でi++により値が増えるため、10回目の出力後に条件が満たされなくなります。

現在のiの値は 0
現在のiの値は 1
現在のiの値は 2
...
現在のiの値は 9

結果: 期待される表示例は、0から9までの値が昇順に並ぶ形です。

この出力例から、最後に表示される値は9であり、10は表示対象に入らないと分かりますし、これが一つの目安です。条件式の<<=の違いは、初心者が見落としやすい注意点です。

while文の使い方

while文の使い方は、固定回数のカウント、複数条件の判定、意図的な無限ループの制御に分けると整理できます。どの形でも、条件が変わるタイミングを明確にすることがループ設計の軸になります。

これらのサンプルコードでは、counterabtruebreakを使って流れを作りますが、覚えておくと役立つでしょう。Javaプログラミングでは同じwhile文でも目的によって読み方が変わるため、変数の役割を名前から判断できるようにしておくと扱いやすくなります。

その考え方を具体化するには、カウンターを使ったループが扱いやすい題材になります。カウンターは現在位置を表す変数であり、配列の添字、試行回数、ページ番号のような値にも応用できると理解できます。

サンプルコード2:カウンターを用いたwhile文

カウンターを使うwhile文では、回数を表す変数を初期化し、条件に達するまで値を増やします。回数が少し変動する可能性がある処理では、for文より条件部分を独立して読める形が合う場合があります。

public class CounterWhileExample {
  public static void main(String[] args) {
    int counter = 0;
    while (counter < 5) { // counterが5未満の場合にループ
      System.out.println("カウンターの値は " + counter);
      counter++; // カウンターを1増やす
    }
  }
}

結果: 期待される出力はカウンターの値は 0からカウンターの値は 4までです。

この例では、counter < 5がループ継続の条件です。表示後にcounter++で値を進めるため、5になった時点で条件がfalseになり、処理が終了します。

カウンターの値は 0
カウンターの値は 1
カウンターの値は 2
...
カウンターの値は 4

結果: 期待される表示例では、カウンターの値が一つずつ増えます。

その出力を確認すると、ループ回数は5回である一方、最後の値は4になると覚えるとよいでしょう。ゼロ始まりのカウンターを使う場面では、この差を意識すると配列のindexとも対応しやすくなります。

複数条件を扱う場合は、片方の変数だけを見て判断しないことが必要です。abのどちらが先に条件を満たさなくなるかで終了位置が決まるため、ループの継続条件は全体の式として読みます。

サンプルコード3:条件式で複数の条件を用いる

複数条件のwhile文では、&&なら両方が真の間だけ続き、||ならどちらかが真の間は続きますし、ここを基本と考えるとよいでしょう。判定が複雑になるほど終了条件を読み間違えやすいため、初心者は変数ごとの変化を表に書くと理解しやすくなります。

public class MultipleConditionsExample {
  public static void main(String[] args) {
    int a = 0, b = 0;
    while (a < 5 && b < 5) { // aもbも5未満の場合にループ
      System.out.println("aの値とbの値は " + a + ", " + b);
      a++;
      b += 2;
    }
  }
}

結果: 期待される出力は、abが条件を満たす組み合わせだけです。

このコードでは、aは1ずつ、bは2ずつ増えます。そのため、bが先に5以上へ近づき、a < 5 && b < 5の条件が崩れた時点でループが止まります。

aの値とbの値は 0, 0
aの値とbの値は 1, 2
aの値とbの値は 2, 4

結果: 期待される表示例では、bが6になる直前までの行が出ますし、ここがポイントです。

一方、&&||に変えると、どちらか一方が条件を満たす限り続くため回数が変わります。論理演算子の差は、while文の注意点として早い段階で押さえておきたい部分です。

一方、終了条件をループの先頭に書けない処理もあります。ユーザー入力を読んでから終了判定を行う場合や、通信で受け取った内容によって停止する場合は、while (true)breakの組み合わせが読みやすいことがあると考えられます。

サンプルコード4:無限ループとその中断

意図的に終わらない形を作る場合は、条件式にtrueを置き、内部のifbreakで終了させます。入力待ちやサーバーの待機処理など、終了タイミングが外から決まるループでよく見る実装パターンです。

public class InfiniteLoopExample {
  public static void main(String[] args) {
    int i = 0;
    while (true) { // 無限ループ
      System.out.println("無限ループ " + i);
      i++;
      if (i >= 5) {
        break; // iが5以上になったらループを抜ける
      }
    }
  }
}

結果: 期待される出力は無限ループ 0から無限ループ 4までです。

この例では、while (true)だけを見ると終わらないように見えます。ただし、i >= 5になったときにbreakが動くため、ループから抜けてプログラムの次の処理へ進みます。

⚠️ 注意: while (true)を使う場合は、必ず到達可能な終了条件を用意すると言えるでしょう。終了条件が入力や通信に依存する場合は、例外処理やタイムアウトも合わせて検討してください。

while文と他のループ構文の比較

Javaにはwhile文以外にも、for文とdo-while文があります。どれもループを作る構文ですが、初期化、条件判定、更新処理をどこに書くかで読みやすさが変わります。

一般に、回数が明確ならfor文、最低一度は処理したいならdo-while文、終了条件が外部から変わるならwhile文が選ばれますが、これは押さえたい点です。公式のfor文説明はOracle Java Tutorialsのfor文解説で確認できます。

for文との比較

for文は、初期化、条件、更新を一行にまとめます。カウンター制御のループでは見通しがよく、配列やリストの全件処理でもよく使われますし、これが一つの目安です。

public class ForLoopExample {
  public static void main(String[] args) {
    for(int i = 0; i < 5; i++) {
      System.out.println("これはfor文です: " + i);
    }
  }
}

結果: 期待される出力はこれはfor文です: 0からこれはfor文です: 4までです。

このコードでは、int i = 0i < 5i++forの丸かっこ内に集約されています。回数を数える意図が先頭で分かるため、単純な反復では読みやすい形になります。

public class WhileLoopExample {
  public static void main(String[] args) {
    int i = 0;
    while(i < 5) {
      System.out.println("これはwhile文です: " + i);
      i++;
    }
  }
}

結果: 期待される出力はこれはwhile文です: 0からこれはwhile文です: 4までです。

同じ処理をwhile文で書くと、初期化と更新が条件式から離れますが、覚えておくと役立つでしょう。その代わり、入力や状態変化を見ながら継続する処理へ拡張しやすく、プログラミングの制御構造として柔軟に使えます。

使い分けると、決まった回数ならfor文、終了タイミングを処理中に判断するならwhile文が自然です。Listの走査と組み合わせる場合は、Java List型完全ガイドの考え方も役立ちます。

do-while文との比較

do-while文は、処理を実行した後に条件を判定するのが基本です。そのため、メニュー表示や入力プロンプトのように、最低一度は処理したい場合に合います。

public class DoWhileExample {
  public static void main(String[] args) {
    int i = 0;
    do {
      System.out.println("これはdo-while文です: " + i);
      i++;
    } while(i < 5);
  }
}

結果: 期待される出力はこれはdo-while文です: 0からこれはdo-while文です: 4までです。

この書き方では、条件判定が末尾にあるため、最初の一回は必ず実行されます。末尾のwhile(i < 5);にはセミコロンが必要で、通常のwhile文との見た目の違いにも注意が必要です。

public class WhileFalseExample {
  public static void main(String[] args) {
    int i = 5;
    while(i < 5) {
      System.out.println("これはwhile文です: " + i);
      i++;
    }
  }
}

結果: 条件が最初からfalseになるため、期待される出力はありません。

この違いにより、while文は「条件を満たす場合だけ動かす」処理に向きます。一方、do-while文は「一度動かしてから継続を判断する」処理で使うと意図が伝わりやすくなります。

while文の応用例

応用例に進む前に、サンプルコードの読み方をそろえておくと混乱が減りますし、ここを基本と考えるとよいでしょう。入力、配列、ファイル、リストはいずれも「次のデータが存在するか」を確認し、存在する間だけ処理するという同じ発想で構成されています。

具体的には、numbers.lengthscanner.nextLine()br.readLine()names.size()のように、オブジェクトや配列の状態を条件に使います。標準APIを扱うため、サンプルコードの前後でimport文にも注目してください。

サンプルコード5:配列の要素を順番に処理する

配列をwhile文で処理する場合は、添字の上限をnumbers.lengthで管理するのが目安です。配列の最後を超えてアクセスすると例外につながるため、条件式にはi < numbers.lengthを使うのが基本形になります。

public class ArrayWhileExample {
  public static void main(String[] args) {
    int[] numbers = {1, 2, 3, 4, 5};
    int i = 0;
    while(i < numbers.length) {
      // 配列の要素にアクセスして表示
      System.out.println("配列の要素: " + numbers[i]);
      i++;
    }
  }
}

結果: 期待される出力は配列の要素: 1から配列の要素: 5までです。

このコードでは、int[] numbersに5個の値を入れ、numbers[i]で順に取り出します。i++がないと同じ要素を読み続けるため、配列処理でも更新処理は欠かせません。

サンプルコード6:ユーザーの入力を受け取る

ユーザー入力を扱うループでは、終了ワードが入力されるまで処理を続ける形がよく使われます。標準入力ではScannerSystem.inを組み合わせ、nextLineで一行ずつ文字列を受け取れますし、ここがポイントです。

import java.util.Scanner;

public class UserInputExample {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String input;

    while(true) {
      System.out.print("入力してください('exit'で終了): ");
      input = scanner.nextLine();

      if("exit".equals(input)) {
        System.out.println("プログラムを終了します。");
        break;
      }
      System.out.println("あなたの入力は: " + input);
    }
    scanner.close();
  }
}

結果: 期待される動作は、exit以外の入力を表示し、exitで終了する流れです。

この例では、文字列比較に"exit".equals(input)を使います。input.equals("exit")でも比較できますが、左側をリテラルにするとinputnullになった場合の例外を避けやすくなるのがポイントです。

その後、入力処理を終えたらscanner.close()でリソースを閉じます。関連する文字列や記号の扱いは、Javaエスケープ処理の10ステップマスターガイドも参考になります。

サンプルコード7:ファイルの内容を行ごとに読む

ファイル読み込みでは、何行あるかを事前に決められない場合があるのが一般的です。そのため、BufferedReaderreadLinenullを返すまで繰り返すwhile文がよく使われます。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileWithWhile {
  public static void main(String[] args) {
    // ファイルパスを指定
    String filePath = "example.txt";

    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
      String line;
      // ファイルの終わりに達するまで読み込む
      while ((line = br.readLine()) != null) {
        // 読み込んだ行を出力
        System.out.println(line);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

結果: example.txtが存在する場合、期待される出力はファイル内容を行ごとに表示する形です。

このコードでは、tryとリソース付きtry文によりBufferedReaderを自動的に閉じます。IOExceptioncatchしているため、ファイルが存在しない場合や読み込みに失敗した場合の処理も置けます。

Hello, World!
Java while loop example.

結果: 期待される入力ファイル例は、2行のテキストを持つexample.txtです。

このファイル内容を読み込むと、各行がそのままコンソールに出力されますが、これは押さえたい点です。ファイルの終端はnullで判定されるため、行数が変わってもwhile文の条件を変える必要はありません。

サンプルコード8:複数のリストを同時に処理する

複数のリストを同時に処理する場合は、同じ添字で対応する値を取り出します。JavaのArrayListでは、要素数をsizeで確認し、値をgetで取得します。

import java.util.ArrayList;

public class MultipleListsExample {
  public static void main(String[] args) {
    ArrayList<String> names = new ArrayList<>();
    ArrayList<Integer> ages = new ArrayList<>();

    names.add("Alice");
    names.add("Bob");
    names.add("Charlie");

    ages.add(25);
    ages.add(30);
    ages.add(35);

    int i = 0;
    // 二つのリストが同じサイズである前提
    while (i < names.size()) {
      // 同じインデックスでデータを取得して処理
      System.out.println("Name: " + names.get(i) + ", Age: " + ages.get(i));
      i++;
    }
  }
}

結果: 期待される出力は、名前と年齢が同じ添字で対応した3行です。

この例では、namesagesの長さが同じである前提で処理しています。一方のリストだけが短い場合、ages.get(i)で範囲外アクセスが起きるため、実装時の注意点になります。

Name: Alice, Age: 25
Name: Bob, Age: 30
Name: Charlie, Age: 35

結果: 期待される表示例では、AliceBobCharlieの順に出ますし、これが一つの目安です。

その前提を安全にしたい場合は、i < names.size() && i < ages.size()のように複数条件で短い側に合わせます。リスト操作を広げるなら、Java List型完全ガイドと合わせて読むと理解がつながります。

注意点と対処法

while文の注意点は、終わらないループ、条件の読み違い、待機処理のCPU負荷に集約できるのが現実的です。どれも構文そのものより、条件と更新の設計が原因になりやすい問題です。

そのため、サンプルコードを書く段階から終了条件をコメントで残し、breakを使う場合は到達できる条件かどうかを確認します。プログラミングの学習では、止まるコードを意識して書くことがwhile文の理解につながります。

特に押さえたいのは、条件式に使う値がループ内で変わるかどうかです。i++、入力の再取得、ファイルの次行読み込みなど、状態を進める処理がなければ、条件が固定されてしまう可能性があると整理できます。

無限ループに陥らないために

無限ループは、条件がいつまでもtrueのまま変わらない状態です。特にwhile文では、条件式の中で使う変数を更新し忘れると止まらなくなります。

public class InfiniteLoopExample {
  public static void main(String[] args) {
    int i = 0;
    while (i >= 0) { // この条件は常にtrueです
      i++;
    }
  }
}

結果: このサンプルコードは終了条件に到達しにくく、期待される通常出力はありません。

この例では、iが増えてもi >= 0の条件が崩れません。整数の上限など細部を別にしても、終了意図がコードから読み取れないため、学習用としては避けたい形です。

public class PreventInfiniteLoop {
  public static void main(String[] args) {
    int i = 0;
    while (true) {
      if (i >= 10) {
        break; // iが10以上になったらループを終了
      }
      i++;
    }
  }
}

結果: 期待される動作は、iが10以上になった時点でループを抜けることです。

この対処例では、while (true)の中に明確なbreak条件があります。ただし、出力がないコードなので、学習中はSystem.out.println(i)を一時的に入れると流れを追いやすくなります。

ただし、終了しない処理をIDEやターミナルで動かした場合は、停止ボタンやCtrl+Cで中断する運用になると理解できます。公開用コードでは、タイムアウト、最大試行回数、例外処理を設ける設計が現実的です。

CPU使用率を抑制する方法

待機ループが何も休まずに回り続けると、CPU時間を消費しやすくなります。リアルタイム性が不要な処理では、Thread.sleepで短い待機を入れる方法があります。

Java SE 21のThread APIでは、sleep(long millis)が現在実行中のスレッドを指定時間だけ休止させるメソッドとして説明されていると覚えるとよいでしょう。詳細はJava SE 21のThread APIで確認できます。

public class CPURateControl {
  public static void main(String[] args) {
    int i = 0;
    while (i < 1000) {
      // 何らかの処理
      i++;

      try {
        Thread.sleep(100); // 100ミリ秒遅延を挿入
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

結果: 期待される動作は、各ループの間に約100ミリ秒の待機が入ることです。

このコードでは、Thread.sleep(100)InterruptedExceptionを投げる可能性があるため、trycatchで囲んでいます。ただし、待機時間の精度はOSや実行環境のスケジューリングに影響されるため、厳密なタイマー用途には別設計が必要です。

カスタマイズ方法

while文を少し発展させると、途中終了、処理のスキップ、入れ子のループを表現できます。どれも使い方を誤ると読みづらくなるため、条件を短く保ち、変数名を具体的にすることが大切になると考えられます。

こうした制御は、同言語の他機能とも組み合わせて使われます。オーバーライドを含むクラス設計の中でループ処理を分けたい場合は、Javaでマスターする!オーバーライドのたった7つのステップも関連します。

while文の中でbreakとcontinueを活用する

breakはループ全体を終了し、continueは現在の回だけをスキップすると言えるでしょう。どちらも制御の流れを変える命令なので、条件式の近くに置き、意図が読み取れるコメントを添えると保守しやすくなります。

public class BreakAndContinueExample {
    public static void main(String[] args) {
        int i = 0;
        while (i < 10) {
            if (i == 5) {
                break; // iが5になった時点でループを終了
            }
            System.out.println("i: " + i);
            i++;
        }

        int j = 0;
        while (j < 10) {
            if (j == 5) {
                j++;
                continue; // jが5の時は出力をスキップ
            }
            System.out.println("j: " + j);
            j++;
        }
    }
}

結果: 期待される出力は、i側が0から4まで、j側が5を除いた0から9までです。

この例では、i == 5breakが動くため、i: 5は出ません。一方、continue側ではj++を先に実行してからスキップしており、更新を忘れないようにしている点が注意点です。

ℹ️ 補足: continueの前に更新処理がないと、同じ値で条件判定に戻り続ける場合があります。while文では特に、スキップ時の更新位置を確認してください。

ネストしたwhile文の作成

ネストしたwhile文は、外側のループ一回ごとに内側のループを最初から回す構造です。表の行と列、二次元配列、組み合わせの列挙などで使われます。

public class NestedWhileExample {
    public static void main(String[] args) {
        int i = 0;
        while (i < 3) {
            int j = 0;
            while (j < 3) {
                System.out.println("i: " + i + ", j: " + j);
                j++;
            }
            i++;
        }
    }
}

結果: 期待される出力は、i: 0, j: 0からi: 2, j: 2までの組み合わせです。

このコードでは、外側のiが変わるたびに内側のjを0へ戻しています。そのため、iが0、1、2の各値に対して、jが0、1、2と進みます。

ただし、ネストが深くなるほど処理回数は増え、読みやすさも落ちますが、覚えておくと役立つでしょう。三重以上のループが必要になった場合は、メソッド分割、データ構造の見直し、クラス設計の整理を検討すると保守しやすくなります。

まとめ

Javaのwhile文は、条件が成立している間だけ処理を続けるループ構文です。基本形は短いものの、条件式、更新処理、終了条件の関係を誤ると、無限ループや想定外の回数につながります。

そのため、初心者はint iのカウンター例から始め、Scannerの入力待ち、BufferedReaderのファイル読み込み、ArrayListの走査へ広げる流れが学びやすいです。サンプルコードを読むときは、条件がいつfalseになるかを必ず確認してください。

一方、回数が決まっている反復ならfor文、最低一度は動かす処理ならdo-while文が合う場合があるのが基本です。while文だけで書こうとせず、目的に合うループを選ぶことが、読みやすいJavaプログラミングにつながります。

その理解を別の課題へ広げる場合は、うるう年判定のように条件分岐が中心の処理を読むのも効果的です。条件式の組み合わせに慣れたい場合は、Javaでうるう年を判定!初心者でも分かる9ステップ解説も関連します。

注意点として、while (true)には到達可能なbreak条件を置き、待機処理ではThread.sleepやタイムアウトを検討するのが目安です。こうした基礎を押さえると、入力、ファイル、リスト、条件分岐を組み合わせた使い方にも対応しやすくなります。

基本的に、while文を設計するときは「開始時点の状態」「続ける条件」「状態を進める処理」「止める条件」を先に言葉で書き出すと、コードに落とし込みやすくなります。特に初心者は、条件式だけを先に書くより、どの値が変わればループが止まるのかを明確にしたほうがミスを減らせますし、ここを基本と考えるとよいでしょう。

具体的には、カウンターならi++、入力ならnextLine、ファイルならreadLineが状態を進める処理になります。これらがwhile文の本体に含まれていない場合、同じ条件で何度も判定し続ける可能性があるため、レビュー時の確認対象になります。

その考え方は、アノテーションやクラス設計を学ぶ段階でも役立ちますし、ここがポイントです。処理の入口と終了条件を分けて読む習慣があると、関連する宣言やメタ情報を扱う場面でも見通しがよくなり、Javaアノテーションの12選!初心者から上級者まで徹底ガイドの内容とも接続できます。

ただし、読みやすさを優先するなら、while文の条件式に長い計算や複雑なメソッド呼び出しを詰め込みすぎないほうが扱いやすくなります。条件の意味が長くなる場合は、真偽値の変数に分けると意図を伝えやすくなるのがポイントです。

この整理を習慣にすると、短い練習コードから長い処理へ移ったときも条件の見落としを減らせます。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。