この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: 繰り返し処理(while文)
SEOタイトル: Java while 文の完全ガイド(do-while / break / continue / Iterator / 無限ループ)

この記事の要点
  • while (cond) { ... } は条件が true の間だけ繰り返す
  • do { ... } while (cond);最低 1 回実行してから条件判定
  • break でループ脱出、continue で次の反復へ
  • 無限ループ while (true) はサーバスレッド / ゲームループ / イベントループに必須
  • Iterator + while パターンは collection を hasNext() で巡回する古典
  • 無限ループは必ず脱出条件 / 割り込みチェックを入れる(CPU 100% 防止)

while 文の基本

int i = 0;
while (i < 5) {
    System.out.println(i);
    i++;
}
// 0 1 2 3 4

// 条件式は boolean 限定(C と違って int は不可)
int n = 10;
// while (n) { ... }   // ❌ コンパイルエラー
while (n > 0) {        // ✅
    n--;
}

// 単文なら波括弧省略可(推奨されない)
int j = 0;
while (j < 3) System.out.println(j++);

// 空のループも書ける(busy-wait、要注意)
while (!isReady()) ;   // 末尾のセミコロンが「空文」

do-while 文

while と違い本体を 1 回は必ず実行してから条件判定します。「最低 1 回はやる」処理に。

import java.util.Scanner;
Scanner sc = new Scanner(System.in);
int input;
do {
    System.out.print("1〜10 で入力: ");
    input = sc.nextInt();
} while (input < 1 || input > 10);   // 範囲外なら再入力

// 同じ処理を while で書くと「最初の入力前」のフラグが必要 → 冗長
boolean valid = false;
while (!valid) {
    System.out.print("1〜10 で入力: ");
    input = sc.nextInt();
    valid = (input >= 1 && input <= 10);
}
項目whiledo-while
条件判定タイミング本体実行前本体実行後
最小実行回数0 回1 回
典型用途「条件が満たされている間」「入力検証」「メニュー表示」

break と continue

// break: ループを完全に抜ける
int i = 0;
while (true) {
    if (i >= 5) break;     // ← ここでループ終了
    System.out.println(i);
    i++;
}

// continue: 残りをスキップして次の反復へ
int j = 0;
while (j < 10) {
    j++;
    if (j % 2 == 0) continue;   // 偶数はスキップ
    System.out.println(j);       // 1, 3, 5, 7, 9
}

// ラベル付き break: ネストしたループを一括脱出
outer:
while (true) {
    while (true) {
        if (found()) break outer;   // ★ outer まで一気に抜ける
    }
}

無限ループ

サーバの待ち受け、ゲームループ、リアルタイム処理などで使われる重要パターン。必ず脱出条件と CPU 休止を入れます。

// ❌ 危険: CPU 100% でブン回る
while (true) {
    if (queue.isEmpty()) continue;     // タイトループ
    process(queue.poll());
}

// ✅ ブロッキングキューを使う(busy-wait しない)
while (!Thread.currentThread().isInterrupted()) {
    try {
        Task task = queue.take();      // 要素が来るまでブロック
        process(task);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        break;
    }
}

// ✅ Thread.sleep で休止(ポーリング)
while (running) {
    if (shouldShutdown()) break;
    poll();
    try {
        Thread.sleep(100);            // 100ms 休む
    } catch (InterruptedException e) {
        break;
    }
}

Iterator + while パターン

Collection を hasNext() で巡回する古典的な書き方。巡回中に要素を削除するときに必須です。

List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));

// ❌ for-each で remove はできない (ConcurrentModificationException)
for (Integer n : list) {
    if (n % 2 == 0) list.remove(n);   // 実行時例外
}

// ✅ Iterator + while で安全に削除
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
    Integer n = it.next();
    if (n % 2 == 0) {
        it.remove();                  // ★ Iterator.remove なら安全
    }
}
System.out.println(list);    // [1, 3, 5]

// Java 8+ では removeIf を使う方が簡潔
list.removeIf(n -> n % 2 == 0);

// ファイル読み取りも while + hasNext のパターン
Scanner sc = new Scanner(new File("input.txt"));
while (sc.hasNextLine()) {
    String line = sc.nextLine();
    process(line);
}
sc.close();

// BufferedReader でも同じ
BufferedReader br = new BufferedReader(new FileReader("input.txt"));
String line;
while ((line = br.readLine()) != null) {
    process(line);
}

while と for の使い分け

シーン推奨理由
回数が決まっている (0〜N-1)for初期化・条件・更新が一箇所
条件次第で回数が変わるwhileシンプル
無限ループwhile(true) / for(;;)慣習
Iterator 巡回for-each (or while)記述短く安全
巡回中に削除するwhile + IteratorConcurrentModificationException 回避
最低 1 回実行do-while条件判定が後

性能

JIT 最適化により、while と for に性能差はほぼ無しです。ループ内の処理(メソッド呼び出し / GC 圧迫 / autoboxing)の方が遥かに影響大。

// ❌ autoboxing 大量発生 → 遅い
long sum = 0L;
Long i = 0L;       // Long (Object)
while (i < 1_000_000L) {
    sum += i;      // Long → long に unbox
    i++;           // long → Long に box
}

// ✅ プリミティブ long
long sum2 = 0L;
long j = 0L;
while (j < 1_000_000L) {
    sum2 += j;
    j++;
}
// → 10 倍以上の差が出ることも

PHP / Python の while と比較

// PHP
$i = 0;
while ($i < 5) {
    echo $i;
    $i++;
}

// do-while
do {
    $line = fgets(STDIN);
} while ($line !== false);

// PHP 独自: while-endwhile(テンプレ向け)
while ($i < 5):
    echo $i;
    $i++;
endwhile;

// 無限ループは true でもよいし 1 でもよい(PHP 緩い)
while (true) { ... }
while (1)    { ... }
# Python
i = 0
while i < 5:
    print(i)
    i += 1

# do-while は無い → break で代用
while True:
    line = input()
    if line == 'quit':
        break

# while-else: ループが break されずに終了した場合だけ else が走る
n = 7
i = 2
while i * i <= n:
    if n % i == 0:
        print('not prime')
        break
    i += 1
else:
    print('prime')   # break で抜けなかったときだけ実行

例外安全とリソース解放

// ❌ 例外で resource が閉じられない
BufferedReader br = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = br.readLine()) != null) {
    process(line);   // ★ ここで例外 → br.close() されない
}
br.close();

// ✅ try-with-resources
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        process(line);
    }
}  // 例外有無に関わらず close される

典型的なバグ

  • 条件更新忘れ: while (i < 10) { ... } 内で i++ 忘れ → 無限ループ
  • off-by-one: <<= の取り違え → 1 件多い / 少ない
  • 浮動小数の条件: while (x != 1.0) は等値比較で永遠に終わらないことがある → 誤差許容で書く
  • busy-wait: 無限ループ + sleep 無し → CPU 100%
  • InterruptedException を握りつぶす → スレッドが終了しない

FAQ

Q: while(true)for(;;) はどちらが速い?
A: 同じバイトコードに最適化されます。好みで OK。while(true) の方が読みやすいという人が多い。

Q: ラベル付き continue はある?
A: あります。continue outer; で外側ループの次の反復へ進めます。break と同様。

Q: while で配列を巡回するのと for-each の違い
A: for-each は内部で Iterator を生成。性能差はほぼ無し(配列の場合は普通の index-for が最速)。可読性は for-each が上。