break と continue

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

break と continue とは

ループの途中で抜ける break と、1 イテレーションだけスキップする continue を使って、繰り返しを自由自在にコントロールしよう。

ループの流れを途中で変える

ここまでのレッスンで for ループや while ループを使って「決まった回数だけ処理を繰り返す」書き方を学びました。今回はそこから一歩進んで、繰り返しの途中で流れを変える ための専用キーワード breakcontinue を取り上げます。この 2 つを覚えると、ループの表現力が一気に広がります。

ループは「最後まで回しきる」が基本ですが、現実の処理ではそうもいきません。「条件に合うものが見つかったらそこで止めたい」「ある条件のときだけ計算をスキップしたい」というケースが山ほどあります。そんなとき登場するのが breakcontinue です。Java だけでなく、JavaScriptPython など他の多くの言語にも同じ名前で存在するので、ここで身につけておくとどこでも使えます。

まずは 2 つの役割を一言でまとめます。breakループそのものから抜けるcontinueその回だけスキップして次の回に進む です。似ているようでまったく違う動きをするので、最初に違いをしっかりおさえましょう。

break ─ ループを途中で抜ける

break は「もうこのループは終わり、外に出る」という命令です。実行された瞬間に、囲っている一番内側のループから抜けて、その続きの行へジャンプします。

Java

public class Demo { public static void main(String[] args) { for (int i = 1; i <= 10; i++) { if (i == 5) { break; } System.out.println(i); } System.out.println("終了"); } }

このコードは 1 2 3 4 終了 と出力します。i == 5 になった瞬間に break が走り、System.out.println(i) には到達しないままループの外へ抜けます。for の更新式 i++ も、抜けたあとはもう実行されません。break は「強制ストップ」のイメージで覚えてください。

「条件に合う最初の 1 件を探す」「上限に達したら終わる」のような処理は break の独擅場です。配列を端から走査して目的の値を見つけたら、それ以上ループを回す必要はありません。break で抜けることで、無駄な比較を防げます。

continue ─ そのイテレーションをスキップする

continue は「今回はもうやめて、次の繰り返しに進む」という命令です。ループ自体は終わらず、continue 以降の処理だけが飛ばされて、for の更新式 (i++ など) を経て次のイテレーションが始まります。

Java

public class Demo { public static void main(String[] args) { for (int i = 1; i <= 6; i++) { if (i % 2 == 1) { continue; } System.out.println(i); } } }

出力は 2 4 6 です。奇数のときは continue が走って System.out.println(i) がスキップされ、偶数のときだけ画面に出ます。ループは i = 6 までしっかり最後まで回り切ります。「飛ばすだけで終わらない」のが continue の本質です。

図で見る制御フロー

言葉だけだと混乱しやすいので、breakcontinue がループの中で何を起こしているかを図にまとめます。

diagram (will load when visible)

ポイントは breakEnd へまっすぐ飛ぶのに対して、continue更新式を経由してから次の判定 に戻る、という違いです。continue を使うとき、ループ変数の更新を本体内でやっていると、その更新がスキップされて無限ループになることがあります (詳しくはあとの「よくある間違い」で説明します)。

多重ループでの break

break を使うとき、必ず覚えておきたいのが「抜けるのは 一番内側のループだけ」というルールです。for の中に for がある二重ループで break を書くと、外側のループはそのまま続きます。

Java

public class Demo { public static void main(String[] args) { for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (j == 2) { break; } System.out.println(i + "-" + j); } } } }

出力は 1-1 2-1 3-1 の 3 行です。内側の forj == 2 のところで毎回 break で抜けますが、外側の fori = 1, 2, 3 と通常どおり回ります。「break は今いる階段の 1 段だけ降りる、ビルから外に出るわけではない」と覚えてください。

ラベル付き break (発展)

外側のループまで一気に抜けたい場面では、Java にはラベル付き break という特別な構文があります。ループの前に outer: のような名前 (ラベル) を書いておき、break outer; のように指定します。

Java

public class Demo { public static void main(String[] args) { outer: for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (i == 2 && j == 2) { break outer; } System.out.println(i + "-" + j); } } System.out.println("終了"); } }

i == 2 && j == 2break outer が走ると、内側だけでなく外側の for まで一気に抜けて 終了 に到達します。便利ですが、読みづらくなりがちで使いすぎると goto 的な複雑さが生まれます。Java のコーディングガイドでも「乱用しない」ことが推奨されており、業務コードでは「メソッドに切り出して return で抜ける」ほうがすっきりすることが多いです。今は「そういう書き方もある」とだけ覚えておけば十分です。

ラベル付き break は最終手段だと思ってください。最初に思いつくのは「メソッドを分けて return で抜ける」「フラグ変数を立てて外側の条件にする」のいずれかです。それでも読みづらくなりそうな深いネストのときだけ、ラベル付き break を検討します。

今回作るメソッド

ここまでの知識を使って、今回は Solution.sumEvenUntil(int n) を作ります。仕様は次のとおりです。

  • 1 から n まで for ループで進める
  • 奇数のときは continue でスキップする
  • 偶数のときだけ合計に足し込む
  • 合計が 50 を超えた時点で break で抜ける

動きを n = 20 で追ってみましょう。i = 1, 3, 5, ...continue でスキップされます。i = 2, 4, 6, ... のときに合計が 2, 6, 12, 20, 30, 42, 56 と増えていきます。i = 14 で合計が 56 になり、50 を超えたので break で抜けます。最終的な戻り値は 56 です。

境界の挙動も整理しておきます。

  • sumEvenUntil(10) ─ 合計は 2 + 4 + 6 + 8 + 10 = 3050 を超えないままループが終わるので 30
  • sumEvenUntil(4) ─ 合計は 2 + 4 = 6。同じくループ終了で 6
  • sumEvenUntil(20) ─ 合計が 56 になった時点で break するので 56
  • sumEvenUntil(100) ─ こちらも i = 14 の時点で 56 に達して break するので 56

つまり、n が十分に大きい場合は答えは常に 56 で固定されます。n が小さい場合は 50 を超えないので「最後まで足した値」を返す、というのがこのメソッドのふるまいです。

よくある間違い

breakcontinue を使い始めると、ほぼ全員が一度はハマる落とし穴があります。代表的な 3 つを紹介します。

  • breakreturn を混同するbreak はループから抜けるだけで、メソッド自体は終わりません。一方 return はメソッドそのものを終了します。「ループの外でまだ処理を続けたいなら break、メソッドごと終わらせたいなら return」と使い分けてください。「break を書いたのに return まで処理が来てしまった」と慌てる人が多いですが、それは break の正しい動きです
  • continue で更新を忘れて無限ループwhile ループの中で continue を使うとき要注意です。int i = 0; while (i < 10) { if (i == 3) continue; i++; } のように、continue の前にループ変数を更新していないと、i = 3 のところで永遠に止まります。for ループなら更新式が自動的に走るので比較的安全ですが、while のときは continue の前に必ず更新を済ませる、または continue の中でも更新する書き方を意識しましょう
  • ラベル付き break の構文ミス — ラベルは outer: のように : をつけて for直前の行に単独で 書きます。for outer:outer for のような書き方はコンパイルエラーです。break outer; の側はラベル名のあとに空白を入れて、最後に ; で締めます。たまにしか使わない構文なので、必要なときは公式ドキュメントで形を確認してください

もうひとつ地味だけど多いのが、「continueif の中に書き忘れる」パターンです。if (...) System.out.println(...); と書くつもりが、continue; を書く位置を間違えて、条件と関係なく毎回スキップしてしまう、というミスです。continue は必ず if のブロックの中に入っているか、ペアの条件を見直しましょう。

breakcontinue はループの流れを乱す力強い道具ですが、使いすぎるとコードが追いにくくなります。「メソッド全体の流れを読まなくても、このループのゴールがわかる」状態を保つのが理想です。乱発したくなったら、「この部分はメソッドに切り出せないか」「フィルタリングしてから処理できないか」と一度立ち止まって考えてみてください。

やってみよう

右側のエディタを開いて、Solution.sumEvenUntil(int n) を完成させましょう。手順は次のとおりです。

  1. 合計を入れる変数 int sum = 0; を用意する
  2. for (int i = 1; i <= n; i++) でループを回す
  3. if (i % 2 == 1) continue; で奇数をスキップする
  4. sum += i; で偶数を合計に足す
  5. if (sum > 50) break; で合計が 50 を超えたらループを抜ける
  6. ループ後に return sum; で結果を返す

テストが緑になったら、自分でいくつか入力を試してみてください。sumEvenUntil(2) sumEvenUntil(8) sumEvenUntil(13) sumEvenUntil(100) あたりを手で計算してから比べると、breakcontinue のふるまいが実感できます。

さらに余裕があれば、breakcontinue の位置を入れ替えたらどうなるか試してみましょう。たとえば「sum += i; の前に break を書いたら?」「continue のかわりに if の中で sum += i; を書いたら?」など、同じロジックを別の形で表現できるか考えてみると理解が深まります。

breakcontinue を使いこなせると、ループの幅が一気に広がります。「全部回す」ではなく「いつ抜ける、いつスキップする」を自分でコントロールできるようになると、書けるコードのレパートリーが何倍にも増えていきます。

よくある質問

Q. Java と他言語の文法はどう違いますか?

A. Java は静的型付けで、変数宣言時に型を明示します(int x = 0;)。中括弧でブロックを表し、文末にセミコロンが必要です。Python の動的型付けや JavaScript の柔軟さに慣れていると最初は窮屈ですが、コンパイル時にバグが発見できる安全性がメリットです。

Q. コードが動かないときに最初に見るべき場所は?

A. コンパイルエラーは行番号とエラー種別(cannot find symbol、incompatible types など)が表示されます。実行時例外はスタックトレースの最初の at ... が原因行です。IDE(IntelliJ / VS Code)の警告も丁寧に潰すと、半分のバグは未然に防げます。

Q. Java の習得後に学ぶべき技術は何ですか?

A. 基本構文を抑えたら java-intermediate(コレクション / ジェネリクス / Stream / 例外)に進み、Spring Boot や Web 開発に展開するのが王道です。クラウド時代は Kotlin / Scala への展開も視野に入りますが、まずは Java 標準を固めるのが効率的です。

次のレッスン

次は FizzBuzz 完成 で、FizzBuzz 完成 を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. break/continue の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. break/continue とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. クラス名は Solution、メソッド名は sumEvenUntil、引数は int n 1 つにすること
  2. for ループで i = 1 から i <= n まで進め、奇数は continue でスキップすること
  3. 偶数を合計に足し、合計が 50超えた (> 50) 時点で break でループを抜けること

入出力例

test-cases.txt

sumEvenUntil(10)30 sumEvenUntil(4)6 sumEvenUntil(20)56 sumEvenUntil(100)56 sumEvenUntil(2)2 sumEvenUntil(1)0 sumEvenUntil(0)0 sumEvenUntil(12)42 sumEvenUntil(14)56 sumEvenUntil(8)20

ヒント

main.java
main.java
学習モード

メモ

break と continue

⌘S で保存