Javaのfor文を完全理解!カウンタ・拡張for・ループ処理を丁寧に解説
生徒
「Javaで同じ処理を何度も繰り返したいんですけど、どうすればいいですか?」
先生
「Javaでは、for文というループ処理の構文を使って、簡単に繰り返し処理を実装できますよ。」
生徒
「for文って、どんなときに使うんですか?」
先生
「例えば、配列の全要素を処理したり、特定の回数だけ処理を繰り返したいときに使います。それでは、基本的な使い方から見ていきましょう!」
1. for文とは?基本的な仕組みを理解しよう
Javaのfor文は、繰り返し処理を実現するための制御構文です。同じ処理を何度も実行したいときに、コードを何行も書く必要がなく、for文を使えば簡潔に記述できます。
for文は主に次の3つの要素で構成されています。
- 初期化式:ループの開始時に一度だけ実行される処理で、通常はカウンタ変数の初期化を行います
- 条件式:ループを継続するかどうかを判定する条件で、この条件がtrueの間は処理が繰り返されます
- 更新式:各ループの終わりに実行される処理で、通常はカウンタ変数の増減を行います
これらの要素を組み合わせることで、柔軟なループ処理を実装することができます。プログラミングにおいて、ループ処理は非常に頻繁に使用される基本的な制御構造ですので、しっかりと理解しておきましょう。
2. 基本的なfor文の書き方と実行例
for文の基本的な構文は次のようになります。初期化式、条件式、更新式をセミコロンで区切って記述します。
基本構文: for (初期化式; 条件式; 更新式) { 繰り返し実行する処理 }
それでは、実際のコード例を見てみましょう。次のプログラムは、0から4までの数字を表示する簡単なfor文の例です。
public class BasicForExample {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println("カウント: " + i);
}
}
}
実行結果は次のようになります。
カウント: 0
カウント: 1
カウント: 2
カウント: 3
カウント: 4
このプログラムでは、変数iが0から始まり、iが5未満の間ループが継続されます。各ループの終わりにiが1ずつ増加していきます。条件式がfalseになった時点でループが終了するため、iが5になった時点で処理が終わります。
3. カウンタ変数の増減パターンを学ぼう
for文のカウンタ変数は、必ずしも1ずつ増やす必要はありません。増減の幅を変えたり、減らしていくこともできます。プログラムの目的に応じて、さまざまなパターンを使い分けることができます。
次の例では、2ずつ増やすパターンと、逆に減らしていくパターンを紹介します。
public class CounterPatternExample {
public static void main(String[] args) {
System.out.println("=== 2ずつ増やすパターン ===");
for (int i = 0; i <= 10; i += 2) {
System.out.println(i);
}
System.out.println("\n=== 10から1まで減らすパターン ===");
for (int i = 10; i >= 1; i--) {
System.out.println(i);
}
}
}
実行結果は次のようになります。
=== 2ずつ増やすパターン ===
0
2
4
6
8
10
=== 10から1まで減らすパターン ===
10
9
8
7
6
5
4
3
2
1
このように、更新式を変更することで、カウンタの増減方法を自由に制御できます。偶数だけを処理したいときや、カウントダウンを実装したいときなどに活用できます。
4. 配列とfor文を組み合わせた処理方法
for文は配列の要素を順番に処理するときに非常に便利です。配列のインデックスは0から始まるため、for文のカウンタと相性が良いのです。
配列の長さは配列名.lengthで取得できるため、配列のサイズが変わっても柔軟に対応できるコードが書けます。次の例では、配列に格納された都市名を順番に表示しています。
public class ArrayForExample {
public static void main(String[] args) {
String[] cities = {"東京", "大阪", "名古屋", "福岡", "札幌"};
System.out.println("日本の主要都市:");
for (int i = 0; i < cities.length; i++) {
System.out.println((i + 1) + "番目: " + cities[i]);
}
// 配列の合計を計算する例
int[] scores = {85, 92, 78, 95, 88};
int total = 0;
for (int i = 0; i < scores.length; i++) {
total += scores[i];
}
double average = (double) total / scores.length;
System.out.println("\n合計点: " + total);
System.out.println("平均点: " + average);
}
}
実行結果は次のようになります。
日本の主要都市:
1番目: 東京
2番目: 大阪
3番目: 名古屋
4番目: 福岡
5番目: 札幌
合計点: 438
平均点: 87.6
このように、配列の全要素に対して処理を行うときは、配列の長さを条件式に使用することで、配列のサイズに依存しない汎用的なコードを書くことができます。
5. 拡張for文の使い方と通常のfor文との違い
Java 5から導入された拡張for文は、配列やコレクションの全要素を順番に処理するときに、より簡潔に記述できる構文です。別名「for-eachループ」とも呼ばれています。
拡張for文の構文は次のようになります。
拡張for文の構文: for (要素の型 変数名 : 配列またはコレクション) { 処理 }
拡張for文の特徴は、インデックスを使わずに直接要素にアクセスできる点です。ただし、インデックスが必要な場合や、配列の一部だけを処理したい場合は、通常のfor文を使う必要があります。
public class EnhancedForExample {
public static void main(String[] args) {
String[] fruits = {"りんご", "バナナ", "オレンジ", "ぶどう", "いちご"};
System.out.println("=== 拡張for文での表示 ===");
for (String fruit : fruits) {
System.out.println(fruit);
}
// 数値配列での使用例
int[] numbers = {10, 20, 30, 40, 50};
int sum = 0;
System.out.println("\n=== 拡張for文での合計計算 ===");
for (int num : numbers) {
sum += num;
System.out.println("現在の合計: " + sum);
}
}
}
実行結果は次のようになります。
=== 拡張for文での表示 ===
りんご
バナナ
オレンジ
ぶどう
いちご
=== 拡張for文での合計計算 ===
現在の合計: 10
現在の合計: 30
現在の合計: 60
現在の合計: 100
現在の合計: 150
拡張for文は、配列やコレクションの全要素を順番に処理するだけの場合に最適です。コードが読みやすく、インデックスの管理ミスも防げるため、積極的に活用しましょう。
6. ネストしたfor文で二重ループを作る方法
for文の中に別のfor文を入れることを「ネスト」といいます。ネストしたfor文を使うと、二次元配列の処理や、九九の表の作成など、より複雑な繰り返し処理を実装できます。
外側のループが1回実行されるたびに、内側のループが完全に実行されます。そのため、外側のループがn回、内側のループがm回実行される場合、内側の処理はn×m回実行されることになります。
次の例では、九九の表を作成するプログラムを紹介します。
public class NestedForExample {
public static void main(String[] args) {
System.out.println("=== 九九の表 ===");
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
int result = i * j;
System.out.print(result + "\t");
}
System.out.println();
}
System.out.println("\n=== 直角三角形のパターン ===");
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("* ");
}
System.out.println();
}
}
}
実行結果は次のようになります。
=== 九九の表 ===
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
=== 直角三角形のパターン ===
*
* *
* * *
* * * *
* * * * *
ネストしたfor文は処理が複雑になりやすいため、インデント(字下げ)をしっかり行い、どのループがどのレベルにあるのかを明確にすることが重要です。
7. for文でよく使うbreakとcontinue文
for文の実行を制御するために、break文とcontinue文があります。これらを使うことで、特定の条件でループを抜けたり、特定の反復をスキップしたりできます。
break文は、ループを途中で終了させるときに使います。条件に合致した時点でループ全体から抜け出します。
continue文は、現在の反復をスキップして次の反復に進むときに使います。ループ自体は継続されます。
これらの制御文を適切に使うことで、より効率的なプログラムを書くことができます。ただし、多用しすぎるとコードが読みにくくなるため、必要な場面で適切に使用することが大切です。
8. for文のパフォーマンスと注意点
for文を使用する際は、パフォーマンスにも注意を払う必要があります。特に大量のデータを処理する場合や、ネストしたループを使用する場合は、処理時間が大幅に増加する可能性があります。
条件式で毎回メソッドを呼び出すと、そのメソッドがループの回数分実行されるため、パフォーマンスに影響します。例えば、配列の長さを取得するlengthは問題ありませんが、計算コストの高いメソッドを条件式に入れると効率が悪くなります。
また、無限ループに陥らないよう、条件式と更新式が適切に設定されているか確認することも重要です。条件式が常にtrueになってしまうと、プログラムが終わらなくなってしまいます。
ネストしたループを使用する場合は、計算量がループの深さの乗数で増えていくことを理解しておきましょう。外側のループがn回、内側のループがm回実行される場合、全体の処理回数はn×mになります。さらにループが深くなると、処理時間が爆発的に増加する可能性があります。
9. 実践的なfor文の活用例
ここでは、実際の開発現場でよく使われるfor文の活用例をいくつか紹介します。これらのパターンを理解することで、より実践的なプログラミングスキルが身につきます。
配列の検索、データの集計、文字列の操作など、さまざまな場面でfor文が活用されています。特に配列やコレクションを扱うプログラムでは、for文は欠かせない存在です。
また、条件に応じて処理を変えたり、特定の要素だけを抽出したりするなど、for文と条件分岐を組み合わせることで、より複雑な処理も実現できます。実際のプログラム開発では、このような複合的な処理が頻繁に必要になります。
10. for文とwhile文の使い分け
Javaには、for文以外にもwhile文やdo-while文といったループ処理の構文があります。それぞれに適した使用場面があり、状況に応じて使い分けることが大切です。
for文は、繰り返し回数が事前に決まっている場合に適しています。配列の全要素を処理する場合や、決まった回数だけ処理を繰り返す場合などです。初期化、条件判定、更新が一箇所にまとまっているため、コードが読みやすくなります。
一方、while文は、繰り返し回数が事前に決まっていない場合や、特定の条件が満たされるまでループを続けたい場合に適しています。ユーザーからの入力を待つ処理や、ファイルの終端まで読み込む処理などで使用されます。
どちらの構文も同じ処理を実現できることが多いですが、コードの可読性や保守性を考えて、状況に応じた適切な構文を選択することが重要です。一般的には、配列やコレクションの処理にはfor文を、条件ベースの繰り返しにはwhile文を使うことが推奨されます。