Java 入門

Java のループ構造

ループ構造(Looping structures)は、Java(およびほぼすべてのプログラミング言語)において、最も基礎的かつ核心となる制御フロー(Control Flow)メカニズムの一つです。設定した特定の条件が真(true)である限り、特定のコードブロックを繰り返し実行することを可能にします。

ループを理解し使いこなすことは、反復作業の自動化、膨大なデータセットの処理、そして動的なインタラクティブ・プログラムの作成において極めて重要です。もしループがなければ、同じ操作を100回実行するために、同じコードを100回コピー&ペーストしなければなりません。そうなれば、プログラムは膨大になり、効率は著しく低下し、メンテナンスは不可能になってしまいます。

本章では、Javaにおける3つの強力なループ構造、forwhiledo-while について深く掘り下げていきます。

1. for ループ:回数を精密に制御する強力なツール

for ループは、強力かつ極めて柔軟なループ構造です。実行前にコードを繰り返す回数が明確に分かっている場合、これが最適な選択肢となります。「カウンタの初期化」「継続条件の判定」「カウンタの更新」という3つの核心要素を一行に集約できるため、非常に簡潔に記述できます。

1.1 for ループの構文

for ループの標準的な構文は以下の通りです。

for (初期化; 条件式; 更新) {
    // 繰り返し実行されるコードブロック
}

for ループの構成要素を分解してみましょう:

  • 初期化 (Initialization): ループが開始される前に一度だけ実行されます。通常は、カウンタ変数の宣言と初期化を行います。例:int i = 0;
  • 条件式 (Condition): 各イテレーション(繰り返し)の前に評価されるブーリアン(Boolean)式です。条件が true であればループ内のコードを実行し、false になればループは即座に終了します。例:i < 10;
  • 更新 (Increment/Decrement): 各ループの実行が終わるたびに実行されます。通常、カウンタ変数の値を更新(増加または減少)させます。例:i++i--

1.2 実戦演習

サンプル 1:数字の 1 から 10 までをプリントする

public class ForLoopExample {
    public static void main(String[] args) {
        // 1. i を 1 で初期化
        // 2. i <= 10 である限りループを継続
        // 3. 各ループ終了後、i の値を 1 増やす (i++)
        for (int i = 1; i <= 10; i++) {
            System.out.println(i); // 現在の i の値を出力
        }
    }
}

サンプル 2:カウントダウン(デクリメント)

public class ForLoopDecrementExample {
    public static void main(String[] args) {
        // 10 から開始し、1 以上の間継続。各ループ後に i を 1 減らす (i--)
        for (int i = 10; i >= 1; i--) {
            System.out.println("カウントダウン: " + i);
        }
    }
}

1.3 拡張 for ループ (for-each ループ)

Java は「拡張 for ループ」(通称 for-each ループ)も提供しています。これは配列(Arrays)やコレクション(Collections)の要素を走査(イテレート)する操作を大幅に簡略化するために設計されています。

構文:

for (データ型 変数名 : 配列またはコレクション) {
    // 各要素に対して実行されるコード
}

サンプル:配列の走査

public class EnhancedForLoopExample {
    public static void main(String[] args) {
        int[] numbers = {10, 20, 30, 40, 50};
        
        // 読み方:「numbers 配列内の各 int 型要素 number に対して...」
        // ループは自動的に配列の値を順番に 'number' 変数に代入します
        for (int number : numbers) {
            System.out.println("要素の値: " + number);
        }
    }
}

注:この書き方は、従来の for (int i = 0; i < numbers.length; i++) よりもエレガントであり、インデックスの指定ミスによる「配列の範囲外アクセス」のリスクを完全に排除できます。

2. while ループ:条件を満たす限り続く探索

while ループも基本的なループ構造の一つです。設定した条件が true である限り、コードブロックを繰り返し実行し続けます。for ループとは異なり、while ループには初期化や更新のメカニズムが組み込まれていません。そのため、変数の初期化はループの外で行い、値の更新はループ内で行う必要があります。

2.1 while ループの構文

while (条件式) {
    // 繰り返し実行されるコードブロック
}

2.2 実戦演習

サンプル 1:数字の 1 から 5 までをプリントする

public class WhileLoopExample {
    public static void main(String[] args) {
        int i = 1; // 1. 手動でカウンタを初期化
        
        while (i <= 5) { // 2. 条件判定
            System.out.println(i);
            i++; // 3. 非常に重要:手動でカウンタを更新!これを忘れると無限ループに陥ります
        }
    }
}

サンプル 2:インタラクティブなプログラム(入力の継続読み取り)

while ループは、ユーザーが特定の値を入力するのを待つなど、「ループ回数が事前に決まっていない」シナリオに非常に適しています。

import java.util.Scanner;

public class WhileLoopInputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number = 0;
        
        // ユーザーが -1 を入力しない限り、ループを継続
        while (number != -1) {
            System.out.print("数字を入力してください (-1 で終了): ");
            number = scanner.nextInt();
            
            if (number != -1) {
                System.out.println("入力された値: " + number);
            }
        }
        System.out.println("プログラムを終了します...");
        scanner.close();
    }
}

3. do-while ループ:最低1回は実行する後判定型

do-while ループは while ループと非常に似ていますが、決定的な違いが一つあります。それは、条件判定がループの実行後に行われる点です。つまり、最初の条件がどうであれ、do-while ループ内のコードブロックは最低でも一度は必ず実行されます。

3.1 do-while ループの構文

do {
    // 繰り返し実行されるコードブロック (最低1回は実行)
} while (条件式); // 注意:ここは必ずセミコロン「;」で終わる必要があります!

3.2 実戦演習

サンプル:ユーザー入力のバリデーション

do-while は「入力バリデーション(妥当性確認)」や「メニュー表示」に最適です。まずユーザーに一度入力させる(またはメニューを見せる)必要があり、その後にその入力が正しいかどうかをチェックするからです。

import java.util.Scanner;

public class DoWhileLoopInputValidation {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int age;
        
        // まず入力を求め、その後にチェックする。不適切なら再入力を繰り返す。
        do {
            System.out.print("年齢を入力してください (0-120): ");
            age = scanner.nextInt();
            
            if (age < 0 || age > 120) {
                System.out.println("無効な年齢です。再入力してください。");
            }
            
        } while (age < 0 || age > 120); // 条件を満たす間はループを継続
        
        System.out.println("確認完了。入力された年齢: " + age);
        scanner.close();
    }
}

4. ループの選び方ガイド

これら3種類のループは、多くの場合互いに書き換えが可能ですが、特定のシナリオに最適なものを選ぶことで、コードの可読性とメンテナンス性を向上させることができます。

  • for ループ: 繰り返しの回数が明確に分かっている場合の「第一選択」です(例:「10回実行する」「要素数5の配列を走査する」など)。
  • while ループ: 繰り返しの正確な回数は不明だが、停止する条件が分かっている場合に適しています。外部要因やリアルタイムのユーザー入力に依存するシナリオに最適です(例:「ファイルの末尾に達するまで読み込む」「ユーザーが終了をクリックするまで待機する」など)。
  • do-while ループ: 条件に関わらず、とにかく最初に一度はコードを実行し、その結果を見て継続を判断したい場合に使用します。典型的な例は「コンソールメニューの表示」や「正しいデータが入力されるまでの強制リトライ」です。