はじめに
Javaの繰り返し処理は、同じ処理を条件に応じて何度も動かすための中心的な構文です。forループ、whileループ、do-whileループを使い分けると、配列の走査、ファイル読み込み、入力チェック、コレクションフレームワークの処理まで自然に組み立てられます。
初心者がつまずきやすいのは、条件式、更新式、ループの制御を別々に覚えてしまう点です。そのため、構文だけでなく、どの場面でどのループを選ぶかまで合わせて整理すると理解しやすくなります。
Javaの公式仕様に近い情報を確認したい場合は、Oracle Java Tutorialsのfor文やOracle Java TutorialsのCollectionsが一次情報として参考になるのが基本です。この記事内のサンプルコードは、期待される出力を明記し、動作を断定する書き方を避けています。
- Java SE 21 / JDK 21
- 標準ライブラリ: java.util、java.io、java.util.stream
- コンパイル例: javac、実行例: java コマンド
- Javaで繰り返し処理を組むときの構文と選び方
- forループ、whileループ、do-whileループの違い
- break、continueを使ったループの制御
- ループのネストで二次元配列を扱う考え方
- StreamAPI、ラムダ式、コレクションフレームワークとの組み合わせ
Javaとは
Javaは、ソースコードをjavacでコンパイルし、生成された.classファイルをJVM上で動かすプログラミング言語です。その仕組みにより、Windows、macOS、Linuxなど異なる環境でも同じプログラムを動かしやすい設計になっています。
この特徴は、Webアプリケーション、業務システム、Android関連の開発、バッチ処理など幅広い用途につながります。Javaで繰り返し処理を理解すると、配列やリストの処理だけでなく、データベースから取得した行の処理にも応用できるのが目安です。
Javaの歴史と特性
Javaは1990年代にSun Microsystemsで開発され、現在はOracleが中心となって仕様や実装を提供しています。公式ドキュメントによれば、Javaの基本構文はclass、public、static、void、mainなどの要素を組み合わせてプログラムの入口を作ります。
その設計では、intやbooleanのような基本型、StringやArrayListのような参照型、例外処理のtry、catch、finallyが明確に分かれますし、ここがポイントです。そのため、繰り返し処理でもデータ型と制御構文の関係を意識する必要があります。
一般に、Javaのコードはクラス単位で構成され、メソッドの中に処理を書きます。forループやwhileループもメソッド内部に配置されることが多く、変数のスコープを理解しておくと、値がどこで使えるかを判断しやすくなるのがポイントです。
Javaの環境構築方法
Javaを学習するには、JDKを導入し、javaとjavacのコマンドが使える状態にします。環境変数PATHが正しく設定されていれば、ターミナルからコンパイルと実行を進められます。
その環境が整ったら、Main.javaのようなファイルを作り、public class Mainの中にpublic static void main(String[] args)を書きますが、これは押さえたい点です。IDEを使う場合でも、内部では同じようにコンパイルと実行が行われると理解できます。
具体的には、IntelliJ IDEA、Eclipse、Visual Studio CodeなどでJavaプロジェクトを作成できます。Java List型完全ガイドのようにリスト処理を扱う記事と合わせると、コレクションフレームワークと繰り返し処理の関係も整理しやすくなるのが一般的です。
繰り返し処理の基本
Javaの繰り返し処理で最初に押さえる結論は、回数が決まっている処理にはforループ、条件が続く間だけ回す処理にはwhileループ、最低一度は処理したい場合にはdo-whileループを選ぶという考え方です。配列やリストの全要素を読むときは、拡張forループやStreamAPIも候補になります。
結果: 期待される動きは、初期化式、条件式、処理本体、更新式の順に評価され、条件式がfalseになるまで処理が続く流れです。
この構文では、int i = 0のように開始値を決め、i < 10のように継続条件を置き、i++で値を更新します。その3要素がそろうため、forループは回数を数えながら進める処理に向いているのが現実的です。
| 分類 | 構文・用語 | 主な用途 | 注意点 | 関連する考え方 |
|---|---|---|---|---|
| 基本 | for | 回数が決まる反復 | 終了条件のずれ | forループ |
| 基本 | while | 条件が続く間の反復 | 更新漏れ | whileループ |
| 基本 | do / while | 一度は動かす反復 | 末尾の; | do-whileループ |
| 制御 | break | 途中終了 | 抜ける範囲 | ループの制御 |
| 制御 | continue | 処理のスキップ | 更新位置 | ループの制御 |
| 配列 | length | 配列の要素数 | 添字範囲 | 配列走査 |
| 文字列 | String | 文字列の保持 | nullへの注意 | 参照型 |
| 出力 | System.out.println | 改行付き表示 | 大量出力 | デバッグ補助 |
| 出力 | System.out.print | 改行なし表示 | 整形崩れ | 表形式 |
| 数値 | i++ | 1増加 | 前置後置の違い | 更新式 |
| 数値 | i-- | 1減少 | 無限ループ | 逆順走査 |
| 条件 | <= | 以下判定 | 境界値 | 終了条件 |
| 条件 | != | 不一致判定 | 参照比較 | whileループ |
| 条件 | true | 無限ループ | 終了手段 | break |
| 集合 | List | 順序付き集合 | 要素変更 | コレクションフレームワーク |
| 集合 | Set | 重複なし集合 | 順序の扱い | コレクションフレームワーク |
| 集合 | Map | キーと値 | キー重複 | entrySet |
| 集合 | ArrayList | 可変長リスト | 挿入コスト | List |
| 集合 | HashSet | 重複排除 | 表示順 | Set |
| 変換 | Arrays.asList | 配列風リスト作成 | 固定長 | サンプルコード |
| 関数型 | lambda | 処理を渡す | 可読性 | ラムダ式 |
| 関数型 | stream | 流れる処理 | 副作用 | StreamAPI |
| 関数型 | filter | 条件抽出 | 条件漏れ | StreamAPI |
| 関数型 | collect | 結果を集約 | 戻り型 | Collectors |
| 関数型 | forEach | 各要素処理 | 途中終了不可 | ラムダ式 |
| 入出力 | BufferedReader | 行単位読み込み | 例外処理 | ファイル処理 |
| 入出力 | FileReader | ファイル入力 | 文字コード | IOException |
| 入出力 | readLine | 1行取得 | null判定 | whileループ |
| 例外 | IOException | 入出力エラー | 握りつぶし | catch |
| 構造 | try-with-resources | 自動クローズ | スコープ | リソース管理 |
forループの使い方
forループは、繰り返し処理の回数をコード上で読み取りやすくする構文です。Javaではforの丸かっこの中に初期化、条件、更新をまとめるため、カウンタ変数の変化を追いやすくなります。
このとき注意したいのは、配列の添字が0から始まる点です。i < array.lengthと書くと最後の要素まで安全に届き、i <= array.lengthにすると範囲外参照につながります。
結果: 期待される出力は、1、2、3、4、5が順番に改行付きで表示される形です。
このサンプルコードでは、int i = 1で開始し、i <= 5が成り立つ間だけSystem.out.println(i)を通りますし、これが一つの目安です。その後にi++で値が増えるため、5を表示した次の評価で条件が終わります。
一方、配列やリストの各要素を順番に扱うだけなら、拡張forループのほうが読みやすい場合があります。Javaアノテーションの記事で扱うようなメタ情報の集合を処理する場面でも、要素単位の反復がよく使われますが、覚えておくと役立つでしょう。
結果: 期待される動きは、配列またはコレクションから要素を1個ずつ取り出し、変数名に入れて本体を処理する流れです。
その構文では添字を直接扱わないため、IndexOutOfBoundsExceptionの発生要因を減らせます。ただし、現在が何番目の要素かを使いたい場合は、通常のforループのほうが扱いやすくなります。
結果: 期待される出力は、りんご、バナナ、ぶどうがこの順番で改行付き表示される形です。
このコードでは、String[]の各要素がfruitに順番に渡されますし、ここを基本と考えるとよいでしょう。配列のサイズを直接書かないため、要素数が変わってもループ本体を修正せずに済みます。
whileループとdo-whileループの使い方
whileループは、条件が成り立つ間だけ処理を続ける構文です。forループと違って更新式が丸かっこの中にまとまらないため、変数の更新をループ本体に書き忘れないことが大切になります。
一方、do-whileループは条件判定が後ろにあるため、処理本体が最低一度は通りますし、ここがポイントです。ユーザー入力を受け取ってから継続可否を判定するような処理では、この性質が役立ちます。
結果: 期待される出力は、1から5までの数値が順番に表示される形です。
このwhileループでは、iを表示した後にi++で値を進めています。その更新がないと条件のi <= 5が変わらず、ループが終わらない状態になると整理できます。
結果: 期待される出力は、1から5までの数値が順番に表示される形です。
このdo-whileループでは、最初にdoブロックが動き、その後にwhile (j <= 5)が評価されます。条件式の後ろに;が必要な点は、whileループと見た目が異なる箇所です。
i++やj++を条件分岐の奥に置くと、特定条件だけ更新されず無限ループにつながることがあると理解できます。繰り返し処理の応用技法
繰り返し処理の基本が見えたら、ループの制御を組み合わせる段階に進めます。Javaではbreakでループを抜け、continueで現在の回だけ処理を飛ばせます。
その制御を使うと、単純に回すだけの処理から、条件に応じて早く終える処理や、不要な要素をスキップする処理へ発展すると覚えるとよいでしょう。ループのネストもこの応用範囲に入り、表や行列のような二次元データを扱うときに使われます。
無限ループの制御
無限ループは常に悪いとは限らず、イベント待機やメニュー処理のように意図して使う場面もあります。ただし、抜ける条件を明確にしないJavaコードは、CPUやメモリなどの資源を消費し続ける可能性があると考えられます。
このときwhile (true)だけを見るのではなく、内部にbreakへ到達する条件があるかを確認します。ループの制御を読むときは、条件式、分岐、更新の3要素を同時に追うと判断しやすくなります。
結果: 期待される出力は、現在のiの値は: 0から現在のiの値は: 9までが順番に表示される形です。
このサンプルコードでは、i == 10になった時点でbreakが働きますが、これは押さえたい点です。そのため、trueを条件にしていても、ループは無条件に続くわけではありません。
ループのネスト
ループのネストは、外側のループ1回に対して内側のループが一通り動く構造です。二次元配列では外側を行、内側を列として考えると、処理の順番を追いやすくなります。
ただし、ループのネストが深くなるほど、処理回数は掛け算で増えます。3行3列なら9回ですが、1000行1000列なら100万回になるため、データ量が増える処理では設計の見直しも必要になると言えるでしょう。
結果: 期待される出力は、行0列0から行2列2まで、9通りの組み合わせが表示される形です。
このコードでは、外側のiが行を表し、内側のjが列を表します。内側のforループが終わってから外側のforループが次の値へ進むため、行ごとの走査になります。
breakとcontinueの活用
breakとcontinueは、繰り返し処理の途中で流れを変えるキーワードです。breakは現在のループを終了し、continueは残りの処理を飛ばして次の反復に移りますし、これが一つの目安です。
一方、使いすぎると処理の出口が増え、読み手が流れを追いにくくなります。特にループのネストと組み合わせる場合は、どのループを抜けるのかをコメントやメソッド分割で明確にするのが現実的です。
結果: 期待される出力は、現在のiの値は: 1と現在のiの値は: 3が表示される形です。
このサンプルコードでは、偶数のときにcontinueで出力を飛ばし、i == 5でbreakにより終了します。ループの制御を理解するには、条件分岐の順番も確認する必要があります。
💡 Tips:breakやcontinueが増えたときは、条件を反転して早期に処理を飛ばすか、判定を別メソッドへ切り出すと読みやすくなるのが基本です。
実用的な繰り返し処理のサンプルコード
実用的なJavaコードでは、繰り返し処理は単独で使われるより、配列、リスト、ファイル、文字列処理と組み合わせることが多くなります。サンプルコードを読むときは、何を反復しているのか、どの条件で終わるのか、出力や戻り値が何かを分けて確認します。
その観点で見ると、forループは要素数が分かるデータ、whileループは読み込める間だけ続くデータ、StreamAPIはコレクションフレームワーク上の変換処理に向いているのが目安です。Javaでうるう年を判定する記事のような条件分岐と合わせると、繰り返しの中で判定する構造も理解しやすくなります。
リストの要素を順番に取り出す
リストの要素を順番に扱う場面では、拡張forループが読みやすい選択肢になります。JavaのArrayListは追加順を保持するため、登録した順に取り出したい処理と相性があるのがポイントです。
結果: 期待される出力は、りんご、ばなな、みかんが追加順に改行付きで表示される形です。
このサンプルコードでは、list.addで要素を追加し、拡張forループでString fruitとして受け取ります。コレクションフレームワークの基本を押さえると、List、Set、Mapの違いも理解しやすくなります。
二次元配列の走査
二次元配列は、行と列を持つ表のようなデータ構造として扱えますが、覚えておくと役立つでしょう。この構造ではループのネストを使い、外側で行を選び、内側で行内の要素を取り出すのが自然です。
結果: 期待される出力は、1 2 3、4 5 6、7 8 9が行ごとに表示される形です。
このコードでは、外側のnumbers.lengthが行数、内側のnumbers[i].lengthが各行の列数を表します。行ごとに列数が違う配列でも、内側で現在行の長さを使えば範囲外参照を避けやすくなります。
ファイルの行ごとの読み込み
ファイルを行単位で読む処理では、読み込める行がなくなるまで繰り返すため、whileループが自然に使えるのが一般的です。JavaではBufferedReaderのreadLineがnullを返した時点で終端と判断できます。
ただし、ファイルパスが存在しない場合や読み取り権限がない場合はIOExceptionが発生します。そのため、ファイル処理では例外を考慮し、try-with-resourcesでリソースを閉じる構造にするのが現実的です。
結果: 期待される出力は、指定したテキストファイルの各行が順番に表示される形です。ファイルが読めない場合は、例外情報が標準エラーへ出る想定になります。
このサンプルコードでは、while((line = br.readLine()) != null)という形で代入と終端判定を同時に行います。読み込み処理は回数が事前に分からないため、whileループの代表的な用途になると整理できます。
繰り返し処理の注意点と対処法
Javaの繰り返し処理で起きやすい問題は、無限ループ、範囲外アクセス、不要な処理の繰り返しです。これらは構文の知識だけでなく、条件と更新の対応を読む習慣で減らせます。
そのため、コードレビューや学習時には、開始値、終了条件、更新箇所、ループの制御、例外の扱いを一緒に確認します。Javaエスケープ処理の記事のように文字列を扱う処理でも、繰り返しの中で特殊文字を変換する場面があると理解できます。
無限ループの回避
無限ループは、条件が変化しないまま真であり続けると発生します。whileループでは更新式が構文上まとまっていないため、特に更新漏れに注意が必要です。
結果: 期待される動きは、iの値は: 0の表示が繰り返され、条件が終わらない状態です。
このコードはiが増えないため、i < 10が常に真のままになります。学習用に問題点を示す例であり、通常の処理として採用しない形です。
結果: 期待される出力は、iの値は: 0からiの値は: 9までが順番に表示される形です。
この修正版では、ループ本体の最後でi++を行うため、条件が少しずつ終了に近づきますし、ここを基本と考えるとよいでしょう。whileループでは、このように条件を変化させる処理があるかを必ず確認します。
処理の効率化
繰り返し処理では、不要な回数だけ処理を回すと読みづらさと負荷が増えます。小さなサンプルコードでは差が目立たなくても、データ件数が増えると処理時間やログ量に影響すると覚えるとよいでしょう。
具体的には、条件分岐で後から不要処理を避けるより、ループ条件自体を目的に合わせるほうが簡潔です。ループ回数の上限が分かっている場合は、forループの条件式で範囲を絞ると読み手にも意図が伝わります。
結果: 期待される出力は、現在の値は: 0から現在の値は: 999までが表示され、500より大きい範囲も通過する形です。
このコードでは、目的が500までなら1000回の反復は過剰になります。条件分岐の中身が空でも、ループ自体は続くため、不要な繰り返し処理が残りますし、ここがポイントです。
結果: 期待される出力は、現在の値は: 0から現在の値は: 500までが表示される形です。
この改善例では、ループ条件の時点で範囲を絞っています。条件式が目的と一致するため、後から不要処理を避ける分岐を読む必要が少なくなります。
System.out.printlnを何度も呼ぶサンプルコードは学習用として読み、実務向けの大量出力ではバッファリングも検討します。繰り返し処理のカスタマイズ方法
Javaの繰り返し処理は、構文だけでなく、ラムダ式、StreamAPI、コレクションフレームワークと組み合わせて表現できます。データの全件処理、条件抽出、変換、集約を扱うときは、通常のforループより宣言的に書ける場合があると言えるでしょう。
ただし、StreamAPIが常に読みやすいとは限りません。途中でbreakしたい処理、複雑な状態変更を伴う処理、例外処理が中心になる処理では、通常のforループやwhileループのほうが扱いやすいことがあります。
ラムダ式とStreamAPIの活用
ラムダ式は、処理そのものを簡潔に書くための構文です。Javaでは->を使い、引数と処理本体を結び付けます。
このラムダ式は、forEach、filter、map、collectなどと組み合わせると、コレクションの繰り返し処理を短く表現できるのが基本です。StreamAPIは、元のコレクションを流れとして扱い、条件抽出や変換をつなげて書く仕組みです。
結果: 期待される意味は、parametersに渡された値を使い、波かっこの中のstatementsを処理するラムダ式の形です。
この構文は、短い処理ならs -> System.out.println(s)のように書けます。一方、処理が長くなる場合は、ラムダ式の中に詰め込むよりメソッドに分けるほうが読みやすくなります。
結果: 期待される出力は、apple、banana、cherryが順番に改行付きで表示される形です。
このサンプルコードでは、Arrays.asListで作ったListに対してforEachを呼び出しているのが目安です。forループより短く書けますが、途中終了を自然に表現しにくい点は覚えておくとよいです。
結果: 期待される出力は、[apple]です。
このコードでは、streamで流れを作り、filterでstartsWithの条件に合う要素だけ残し、Collectors.toListでリストへ戻しています。StreamAPIとラムダ式は、条件抽出を読みやすくつなげたい場面に向きます。
コレクションフレームワークの活用
コレクションフレームワークは、複数の値を扱うためのJava標準の仕組みです。Listは順序を持ち、Setは重複を避け、Mapはキーと値の対応を扱いるのがポイントです。
その性質に合わせて繰り返し処理を選ぶと、コードの意図が伝わりやすくなります。順序が意味を持つ一覧ならList、重複排除が目的ならSet、キーごとの集計ならMapという切り分けが一般的です。
結果: 期待される出力は、apple、banana、cherryがリストの順番で表示される形です。
このサンプルコードでは、Listの順序を保ったまま拡張forループで取り出しています。通常のforループでも書けますが、添字を使わない処理なら拡張forループのほうが目的を読み取りやすくなります。
結果: 期待される出力は、apple、banana、cherryの各要素が表示される形です。ただし、HashSetでは表示順がリストと同じになるとは限りません。
このコードでは、HashSetを使ってSetを作成しているのが一般的です。Setは重複を持たない集合なので、同じ値を複数追加しても1要素として扱われます。
一方、順序を保ちたい場合はLinkedHashSet、並び順を制御したい場合はTreeSetなどの選択肢があります。コレクションフレームワークは型ごとに性質が違うため、繰り返し処理の前にデータ構造を選ぶことが大切になるのが現実的です。
💡 Tips: StreamAPI、ラムダ式、コレクションフレームワークは組み合わせて使えますが、学習初期は通常のforループで流れを理解してから置き換えると混乱しにくくなります。
まとめ
Javaの繰り返し処理は、forループ、whileループ、do-whileループの違いを押さえると、用途ごとの選び方が見えてきます。回数が決まる処理にはforループ、終了条件がデータ次第の処理にはwhileループ、最低一度の実行が必要な処理にはdo-whileループが向きますが、これは押さえたい点です。
その基礎に加えて、breakとcontinueによるループの制御、ループのネストによる二次元データの走査、StreamAPIとラムダ式による宣言的な処理を使い分けると、Javaコードの表現範囲が広がります。サンプルコードを読むときは、開始値、条件、更新、出力の関係を順に追うと理解しやすくなります。
具体的には、配列の走査ではlength、List処理では拡張forループ、ファイル読み込みではreadLineとwhileループ、条件抽出ではStreamAPIのfilterがよく使われますし、これが一つの目安です。Javaのオーバーライド解説と合わせると、メソッド設計と繰り返し処理の関係もつかみやすくなります。
ただし、短く書ける構文が常に読みやすいとは限りません。ループの制御が複雑な場合は通常のforループやwhileループを使い、単純な抽出や変換ならStreamAPIとラムダ式を使う、という切り分けが実用的です。
Javaで繰り返し処理を学ぶ目的は、構文を暗記することだけではありません。データ構造に合わせて処理を選び、無限ループや範囲外アクセスを避け、読み手が追いやすいサンプルコードを書けるようになることが実践につながります。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


