for ループ(Java)
繰り返し処理の基本構文です。『for』文は「初期化」「条件式」「更新式」の3つを1行にまとめて書けるため、カウンタ変数を使ったループに適しています。カウントアップ・カウントダウン・ステップ変更から、break・continueによるループ制御、ネストしたループとラベル付きbreakまで解説します。
構文
// 基本的なfor文の構文です
for (初期化式; 条件式; 更新式) {
// 条件式がtrueの間、繰り返し実行されます
}
// カウントアップ(0から始めてn未満まで)の典型的な書き方です
for (int i = 0; i < n; i++) {
// iが0, 1, 2 ... n-1 と変化します
}
// カウントダウン(nから1まで)の書き方です
for (int i = n; i >= 1; i--) {
// iがn, n-1 ... 1 と変化します
}
// ステップを変更する書き方です(2ずつ加算)
for (int i = 0; i < n; i += 2) {
// iが0, 2, 4 ... と変化します
}
// break でループを途中終了します
for (int i = 0; i < n; i++) {
if (条件) {
break; // ループを抜けます
}
}
// continue でその回の処理をスキップします
for (int i = 0; i < n; i++) {
if (条件) {
continue; // 残りの処理をスキップして次の繰り返しへ進みます
}
// continueされなかった場合の処理
}
// ラベル付きbreakでネストしたループを一度に抜けます
outer:
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (条件) {
break outer; // outerラベルのループごと終了します
}
}
}
for文の各部の役割
| 部分 | タイミング | 説明 |
|---|---|---|
| 初期化式 | ループ開始前に1回だけ実行 | カウンタ変数の宣言と初期値の設定を行います。 |
| 条件式 | 各繰り返しの前に評価 | true なら処理ブロックを実行し、false になるとループを終了します。 |
| 更新式 | 各繰り返しの後に実行 | カウンタ変数を増減・更新します。 |
サンプルコード
ForLoopBasic.java
public class ForLoopBasic {
public static void main(String[] args) {
// --- カウントアップ ---
// 呪術廻戦の主要キャラクターを順番に出力します
String[] sorcerers = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇", "五条悟", "乙骨憂太"};
System.out.println("=== 呪術師一覧(カウントアップ)===");
for (int i = 0; i < sorcerers.length; i++) {
System.out.println((i + 1) + "番目: " + sorcerers[i]);
}
// --- カウントダウン ---
// 逆順に出力します
System.out.println("=== 呪術師一覧(カウントダウン)===");
for (int i = sorcerers.length - 1; i >= 0; i--) {
System.out.println(sorcerers[i]);
}
// --- ステップを2にして偶数インデックスのみ取得 ---
System.out.println("=== 偶数インデックスの呪術師 ===");
for (int i = 0; i < sorcerers.length; i += 2) {
System.out.println("インデックス" + i + ": " + sorcerers[i]);
}
}
}
javac ForLoopBasic.java java ForLoopBasic === 呪術師一覧(カウントアップ)=== 1番目: 虎杖悠仁 2番目: 伏黒恵 3番目: 釘崎野薔薇 4番目: 五条悟 5番目: 乙骨憂太 === 呪術師一覧(カウントダウン)=== 乙骨憂太 五条悟 釘崎野薔薇 伏黒恵 虎杖悠仁 === 偶数インデックスの呪術師 === インデックス0: 虎杖悠仁 インデックス2: 釘崎野薔薇 インデックス4: 乙骨憂太
ForLoopBreakContinue.java
public class ForLoopBreakContinue {
public static void main(String[] args) {
// 呪術師と呪力レベルのデータです
String[] names = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇", "五条悟", "七海建人"};
int[] levels = {80, 70, 65, 100, 72};
// --- break: 特定条件でループを終了 ---
// 呪力レベルが100の術師を見つけたら探索を打ち切ります
System.out.println("=== 特級術師を探索(break)===");
for (int i = 0; i < names.length; i++) {
System.out.println(names[i] + "を確認中...");
if (levels[i] == 100) {
System.out.println("特級術師を発見: " + names[i]); // 五条悟で終了します
break;
}
}
// --- continue: 特定の要素をスキップ ---
// 呪力レベルが70未満の術師はリストから除外します
System.out.println("=== 呪力レベル70以上の術師(continue)===");
for (int i = 0; i < names.length; i++) {
if (levels[i] < 70) {
continue; // 70未満はスキップして次のiへ進みます
}
System.out.println(names[i] + "(呪力レベル: " + levels[i] + ")");
}
}
}
javac ForLoopBreakContinue.java java ForLoopBreakContinue === 特級術師を探索(break)=== 虎杖悠仁を確認中... 伏黒恵を確認中... 釘崎野薔薇を確認中... 五条悟を確認中... 特級術師を発見: 五条悟 === 呪力レベル70以上の術師(continue)=== 虎杖悠仁(呪力レベル: 80) 伏黒恵(呪力レベル: 70) 五条悟(呪力レベル: 100) 七海建人(呪力レベル: 72)
ForLoopNested.java
public class ForLoopNested {
public static void main(String[] args) {
// 領域展開の組み合わせ一覧を作成します(ネストしたfor文)
String[] domains = {"無量空処", "蒼", "赫"};
String[] users = {"五条悟", "七海建人", "虎杖悠仁"};
System.out.println("=== 領域と術師の組み合わせ(ネストしたfor)===");
for (int i = 0; i < users.length; i++) {
for (int j = 0; j < domains.length; j++) {
System.out.println(users[i] + " × " + domains[j]);
}
}
// --- ラベル付きbreak: 外側のループまで一気に抜ける ---
// 「五条悟」と「無量空処」の組み合わせを見つけたら全ループを終了します
System.out.println("=== ラベル付きbreakで特定の組み合わせを探索 ===");
outer:
for (int i = 0; i < users.length; i++) {
for (int j = 0; j < domains.length; j++) {
String combo = users[i] + " × " + domains[j];
System.out.println("確認: " + combo);
if (users[i].equals("五条悟") && domains[j].equals("無量空処")) {
System.out.println("発見!" + combo);
break outer; // outerラベルのループ(外側のfor)を終了します
}
}
}
System.out.println("探索終了");
}
}
javac ForLoopNested.java java ForLoopNested === 領域と術師の組み合わせ(ネストしたfor)=== 五条悟 × 無量空処 五条悟 × 蒼 五条悟 × 赫 七海建人 × 無量空処 七海建人 × 蒼 七海建人 × 赫 虎杖悠仁 × 無量空処 虎杖悠仁 × 蒼 虎杖悠仁 × 赫 === ラベル付きbreakで特定の組み合わせを探索 === 確認: 五条悟 × 無量空処 発見!五条悟 × 無量空処 探索終了
よくあるミス1: Off-by-one エラー(i <= arr.length)
配列のインデックスは 0 から始まり、最大値は length - 1 です。終了条件を i <= arr.length にすると存在しないインデックスにアクセスして ArrayIndexOutOfBoundsException が発生します。
OffByOneNg.java
public class OffByOneNg {
public static void main(String[] args) {
String[] sorcerers = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇", "五条悟", "乙骨憂太"};
// <= にしてしまうと i が 5 になったときに範囲外アクセスが発生します
for (int i = 0; i <= sorcerers.length; i++) {
System.out.println(sorcerers[i]); // i=5 で例外が発生します
}
}
}
javac OffByOneNg.java java OffByOneNg 虎杖悠仁 伏黒恵 釘崎野薔薇 五条悟 乙骨憂太 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 at OffByOneNg.main(OffByOneNg.java:7)
終了条件は i < arr.length(厳密な不等号)が基本です。
OffByOneOk.java
public class OffByOneOk {
public static void main(String[] args) {
String[] sorcerers = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇", "五条悟", "乙骨憂太"};
// < にすることで i は 0〜4 の範囲に収まります
for (int i = 0; i < sorcerers.length; i++) {
System.out.println(sorcerers[i]);
}
}
}
javac OffByOneOk.java java OffByOneOk 虎杖悠仁 伏黒恵 釘崎野薔薇 五条悟 乙骨憂太
よくあるミス2: 更新式を忘れて無限ループになる
for 文の更新式(i++ など)を書き忘れると、カウンタ変数が変化しないため条件式が常に true になり無限ループが発生します。
InfiniteLoopNg.java
public class InfiniteLoopNg {
public static void main(String[] args) {
String[] sorcerers = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇"};
// 更新式を書き忘れると i が 0 のまま変化しません
for (int i = 0; i < sorcerers.length; /* i++ を忘れた */) {
System.out.println(sorcerers[i]); // 虎杖悠仁 が無限に出力されます
}
}
}
javac InfiniteLoopNg.java java InfiniteLoopNg 虎杖悠仁 虎杖悠仁 虎杖悠仁 (無限に続く...)
更新式を追加することでループが正常に終了します。
InfiniteLoopOk.java
public class InfiniteLoopOk {
public static void main(String[] args) {
String[] sorcerers = {"虎杖悠仁", "伏黒恵", "釘崎野薔薇"};
// i++ を追加することで毎回インデックスが進みます
for (int i = 0; i < sorcerers.length; i++) {
System.out.println(sorcerers[i]);
}
}
}
javac InfiniteLoopOk.java java InfiniteLoopOk 虎杖悠仁 伏黒恵 釘崎野薔薇
概要
for 文は繰り返し回数があらかじめ決まっているときや、配列・インデックスを使いたいときに適しています。初期化式・条件式・更新式はそれぞれ省略できますが、条件式を省略すると無限ループになるため break での脱出が必要です。
break はループを即座に終了します。continue はその回の残り処理をスキップして次の繰り返しに進みます。ラベル付き break はネストが深い場合に有効ですが、使いすぎるとコードが読みにくくなります。メソッド分割などで構造を整理する方法も検討できます。
配列やコレクションの全要素を順に処理する場合は、インデックスが不要であれば拡張 for 文(for-each 文)を使うとシンプルに書けます。コレクションを使ったループについては『Stream forEach / reduce』も参考になります。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。