Java | 基礎文法:do-while

Java Java
スポンサーリンク

do-while の全体像

do-while は「本体を必ず1回実行してから条件を判定し、条件が true の間は繰り返す」構文です。通常の while と違い、最初の1回は無条件で実行されます。ユーザー入力のプロンプト表示、最低1回は処理したい初期化や試行に向いています。構文は「do { 本体 } while (条件);」で、末尾のセミコロンが必須です。


基本形と動き

最小の書式と1回保証

int i = 0;
do {
    System.out.println(i);
    i++;
} while (i < 3);
Java

本体が先に1回実行され、その後で条件 i < 3 を判定します。i が初回から 3 以上でも、本体は1度だけ動く点が「通常の while」との最大の違いです。

初期化と試行に向く理由

「実行してみないと次の条件が分からない」ケースに自然に書けます。ファイルやソケットの読み取り、ユーザー入力のバリデーション、リトライの1回目を必ず動かす設計に適しています。


重要ポイントの深掘り:条件設計と更新位置

条件の比較軸と更新のペア

条件は「次の周回を続けるかどうか」を判定します。増加なら「未満」、減少なら「より大きい」を軸にし、本体中でその軸に対応した更新を必ず通過させます。

int remain = 3;
do {
    System.out.println("remain=" + remain);
    remain--; // 条件 remain > 0 に対応する更新
} while (remain > 0);
Java

更新が分岐でスキップされると、意図せぬ無限ループや取りこぼしにつながります。本体の構造は「必ず更新が通る」ように設計します。

continue と更新の一貫性

do-whilecontinue を使うと、その周回の残りをスキップして条件判定へ進みます。更新が後半にある場合は、continue 前に更新を済ませるか、更新を先頭へ寄せると安全です。

int i = 0;
do {
    if (i == 2) {
        i++;      // スキップ前に更新
        continue; // 条件判定へ
    }
    System.out.println(i);
    i++;
} while (i < 5);
Java

while との違いと使い分け

初回実行の保証が必要かどうか

while は条件が false なら一度も動きません。do-while は初回必ず動きます。プロンプト表示や、初回で状態を確定させたい処理なら do-while。開始前から終了が決まっているなら while が素直です。

int n = 10; // 例:開始前に n が 0 の可能性
while (n > 0) { /* 0なら一度も動かない */ }

do { /* 0でも一度は動く */ } while (n > 0);
Java

入力・読み取りの定番パターン

ユーザー入力の再試行

import java.util.Scanner;

public class Prompt {
    public static void main(String[] args) {
        Scanner sc = new Scanner("abc\n42\n");
        String line;
        do {
            System.out.print("数字を入力してください: ");
            line = sc.nextLine();
        } while (!line.matches("\\d+"));
        System.out.println("OK: " + line);
    }
}
Java

プロンプトは1回必ず表示し、その後「条件を満たすまで」繰り返します。検証ロジックを条件に直接書くと、読みやすさと安全性が両立します。

ストリームの読み取り(空でない限り続行)

import java.util.Scanner;

public class ReadLines {
    public static void main(String[] args) {
        Scanner sc = new Scanner("A\nB\n\nC\n");
        String line;
        do {
            line = sc.nextLine();
            if (line.isBlank()) break;  // 番兵値で終了
            System.out.println("read: " + line);
        } while (true);
    }
}
Java

「空行が来たら終了」などの番兵値(センチネル)と相性が良く、1行目は必ず処理されます。


リトライと上限(1回保証+安全弁)

成功するまで、ただし上限まで

int attempts = 0;
boolean success;
do {
    success = tryOnce(); // 1回は必ず試す
    attempts++;
} while (!success && attempts < 3);
System.out.println(success ? "OK" : "NG");

static boolean tryOnce() { return Math.random() < 0.4; }
Java

「1回目は必ず実行」「成功なら終了」「失敗でも上限まで」は実務でよく使う形です。条件は「成功していない かつ 上限未満」の合成にすると、安全弁が効きます。


よくある落とし穴と対策

条件が常に真になる設計ミス

条件を状態変化に結びつけないと、永遠に続きます。各周回で必ず「条件を変える更新」が通ること、終了可能な分岐(break)があることを確認します。

continue で更新が飛ぶ問題

continue を入れる分岐でも更新が必ず走るように、先頭更新や分岐内更新で一貫性を保ちます。更新漏れは無限ループの主因です。

セミコロンの書き忘れ

do { ... } while (条件); の末尾セミコロンは必須です。ここを忘れると構文エラーになります。while と違う点として習慣化します。


実用例で身につける

メニュー選択(無効入力を弾いて再表示)

import java.util.Set;

public class Menu {
    public static void main(String[] args) throws Exception {
        java.io.BufferedReader br = new java.io.BufferedReader(new java.io.StringReader("x\n2\n"));
        Set<String> valid = Set.of("1", "2", "3");
        String choice;
        do {
            System.out.println("1:新規 2:保存 3:終了");
            choice = br.readLine();
        } while (choice != null && !valid.contains(choice));
        System.out.println("選択: " + choice);
    }
}
Java

初期化後の検証ループ(最低1回のチェック)

public class InitAndCheck {
    public static void main(String[] args) {
        int value = init(); // 初期化の結果によらず一度チェックしたい
        do {
            System.out.println("check: " + value);
            value = adjust(value);     // 調整して条件に近づける
        } while (!isGood(value));
    }

    static int init() { return 0; }
    static int adjust(int v) { return v + 1; }
    static boolean isGood(int v) { return v >= 3; }
}
Java

設計の指針(重要部分のまとめ)

do-while は「最低1回は本体を実行する」ことが前提の繰り返しに最適です。条件の比較軸と更新の変化軸をペアで設計し、各周回で更新が必ず通る構造にします。continue を使う分岐でも更新一貫性を守り、必要なら番兵値や上限を条件へ組み込んで安全弁を用意します。初回無条件実行が不要なら while、回数が決まっているなら for を選び、使い分けを明確にすることで、読み手は意図を瞬時に理解できます。

タイトルとURLをコピーしました