Javaの配列のループ方法まとめ!for/foreach/while の違いを丁寧に紹介
生徒
「Javaで配列の要素を順番に処理するには、どうすればいいんですか?」
先生
「Javaでは、配列の要素を順番に処理するために、いくつかのループ方法が用意されています。主にfor文、拡張for文(foreach)、while文の3つがありますよ。」
生徒
「それぞれどんな違いがあるんですか?使い分けるポイントも知りたいです!」
先生
「それでは、それぞれのループ方法の特徴と使い分けを詳しく見ていきましょう!」
1. Javaの配列とループ処理の基本
Javaでプログラミングを始めると、必ずと言っていいほど登場するのが「配列」と「ループ処理」です。配列とは、同じ種類のデータをひとまとめにして管理できる仕組みで、複数の値を効率よく扱えるようになります。
配列のループ処理とは、その配列に入っているデータを先頭(0番目)から順番に取り出し、表示したり計算したりといった処理を自動で繰り返すことを指します。1つずつ手動で処理を書く必要がないため、プログラムが短く、分かりやすくなります。
たとえば、テストの点数を配列にまとめて保存しておけば、全員分の点数を表示したり、合計点や平均点を計算したりすることが簡単にできます。実務でも「一覧データを順番に処理する」という場面は非常に多く、配列とループの組み合わせは基本中の基本です。
まずは、配列を作るところから見ていきましょう。Javaでは、次のように配列を宣言して使います。
public class ArrayLoopBasic {
public static void main(String[] args) {
// 数字をまとめて管理する配列
int[] numbers = {10, 20, 30, 40, 50};
// 文字をまとめて管理する配列
String[] fruits = {"りんご", "バナナ", "オレンジ"};
System.out.println("numbersの要素数: " + numbers.length);
System.out.println("fruitsの要素数: " + fruits.length);
}
}
この例では、int型の配列とString型の配列を作成しています。配列に入っているデータの個数は、lengthというプロパティを使うことで簡単に確認できます。
配列は「複数のデータをまとめて扱う箱」、ループ処理は「その箱の中身を順番に取り出す仕組み」と考えると理解しやすいでしょう。次の章からは、この配列を実際にループで処理する方法を、初心者の方にも分かりやすく解説していきます。
2. for文による配列のループ処理
for文は、Javaで最も基本的なループ構文です。配列のインデックスを使って、各要素に順番にアクセスできます。for文は、ループの回数が明確で、インデックス番号が必要な場合に特に適しています。
for文の基本構文は次のとおりです。初期化式でループカウンタを設定し、条件式でループを継続する条件を指定し、増減式でカウンタを更新します。
public class ForLoopExample {
public static void main(String[] args) {
int[] scores = {85, 92, 78, 90, 88};
System.out.println("=== for文による配列のループ ===");
// 基本的なfor文で配列をループ
for (int i = 0; i < scores.length; i++) {
System.out.println("scores[" + i + "] = " + scores[i]);
}
// 配列の合計を計算
int total = 0;
for (int i = 0; i < scores.length; i++) {
total += scores[i];
}
System.out.println("合計点: " + total);
System.out.println("平均点: " + (total / scores.length));
}
}
=== for文による配列のループ ===
scores[0] = 85
scores[1] = 92
scores[2] = 78
scores[3] = 90
scores[4] = 88
合計点: 433
平均点: 86
for文の特徴は、インデックス番号を直接扱えることです。そのため、配列の特定の要素を変更したり、インデックス番号を表示したりする場合に便利です。また、配列を逆順にループしたい場合も、for文なら簡単に実現できます。
逆順にループする場合は、初期化式をi = scores.length - 1とし、条件式をi >= 0、増減式をi--とすることで実現できます。
3. 拡張for文による配列のループ処理
拡張for文(foreach文とも呼ばれます)は、Java 5から導入された、より簡潔に配列やコレクションをループできる構文です。インデックスを意識する必要がなく、配列の各要素に直接アクセスできます。
拡張for文は、配列の全要素を順番に処理する場合に最適です。コードがシンプルで読みやすく、インデックスの範囲外エラーを防げるというメリットがあります。ただし、インデックス番号が必要な場合や、配列の要素を変更したい場合には適していません。
public class EnhancedForLoopExample {
public static void main(String[] args) {
String[] cities = {"東京", "大阪", "名古屋", "福岡", "札幌"};
System.out.println("=== 拡張for文による配列のループ ===");
// 拡張for文で配列をループ
for (String city : cities) {
System.out.println("都市名: " + city);
}
// 配列の要素数をカウント
int count = 0;
for (String city : cities) {
count++;
}
System.out.println("都市の数: " + count);
// 特定の文字を含む要素を探す
System.out.println("\n「阪」を含む都市:");
for (String city : cities) {
if (city.contains("阪")) {
System.out.println(city);
}
}
}
}
=== 拡張for文による配列のループ ===
都市名: 東京
都市名: 大阪
都市名: 名古屋
都市名: 福岡
都市名: 札幌
都市の数: 5
「阪」を含む都市:
大阪
拡張for文の構文はfor (データ型 変数名 : 配列名)という形式です。ループのたびに、配列の次の要素が変数に代入されます。コードが短く、可読性が高いため、単純に配列の全要素を読み取る処理には拡張for文を使うことをおすすめします。
4. while文による配列のループ処理
while文は、条件が真である限りループを継続する構文です。配列のループにも使用できますが、for文に比べると使用頻度は低いです。while文は、ループ回数が事前に分からない場合や、特定の条件でループを終了したい場合に適しています。
配列をループする際にwhile文を使う場合は、インデックス変数を自分で初期化し、ループ内で更新する必要があります。そのため、記述量が増え、インデックスの管理ミスが発生しやすくなります。しかし、複雑な条件でループを制御したい場合には有効です。
public class WhileLoopExample {
public static void main(String[] args) {
double[] prices = {150.5, 200.0, 180.75, 220.3, 195.0};
System.out.println("=== while文による配列のループ ===");
// while文で配列をループ
int index = 0;
while (index < prices.length) {
System.out.println("商品" + (index + 1) + "の価格: " + prices[index] + "円");
index++;
}
// 特定の条件でループを終了する例
System.out.println("\n200円以上の商品を探す:");
index = 0;
while (index < prices.length) {
if (prices[index] >= 200.0) {
System.out.println("最初に見つかった商品: 商品" + (index + 1) + " (" + prices[index] + "円)");
break; // 条件を満たしたらループを終了
}
index++;
}
}
}
=== while文による配列のループ ===
商品1の価格: 150.5円
商品2の価格: 200.0円
商品3の価格: 180.75円
商品4の価格: 220.3円
商品5の価格: 195.0円
200円以上の商品を探す:
最初に見つかった商品: 商品2 (200.0円)
while文は柔軟性が高く、複雑な条件でのループ制御が可能です。ただし、配列のループにはfor文や拡張for文の方が適している場合が多いため、用途に応じて使い分けることが重要です。
5. 各ループ方法の特徴と使い分け
ここまで紹介した3つのループ方法には、それぞれ異なる特徴があります。適切なループ方法を選択することで、コードの可読性と保守性が向上します。
適している場面:
- インデックス番号が必要な場合
- 配列の要素を変更したい場合
- 逆順や特定の間隔でループしたい場合
- ループ回数が明確な場合
メリット:インデックスを直接扱えるため、柔軟な処理が可能です。
デメリット:記述量が多く、インデックスの管理ミスが発生する可能性があります。
適している場面:
- 配列の全要素を順番に読み取るだけの場合
- インデックス番号が不要な場合
- シンプルで読みやすいコードを書きたい場合
メリット:コードが簡潔で、インデックスの範囲外エラーが発生しません。
デメリット:インデックス番号にアクセスできず、要素の変更ができません。
適している場面:
- 複雑な条件でループを制御したい場合
- ループ回数が事前に分からない場合
- 途中でループを終了する可能性がある場合
メリット:柔軟な条件制御が可能です。
デメリット:記述量が多く、インデックスの管理を自分で行う必要があります。
一般的には、単純に配列の全要素を処理する場合は拡張for文、インデックスが必要な場合はfor文、複雑な条件がある場合はwhile文を使うのがおすすめです。
6. 多次元配列のループ処理
Javaでは、配列の配列である多次元配列を作成できます。二次元配列は、表やマトリックスのようなデータ構造を表現するのに便利です。多次元配列をループする場合は、ネストしたループを使用します。
二次元配列の各要素にアクセスするには、外側のループで行を、内側のループで列を処理します。for文と拡張for文のどちらでも多次元配列をループできます。
public class MultiDimensionalArrayLoop {
public static void main(String[] args) {
// 二次元配列の宣言と初期化
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println("=== for文による二次元配列のループ ===");
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
System.out.println("\n=== 拡張for文による二次元配列のループ ===");
for (int[] row : matrix) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
// 二次元配列の合計を計算
int sum = 0;
for (int[] row : matrix) {
for (int value : row) {
sum += value;
}
}
System.out.println("\n配列の全要素の合計: " + sum);
}
}
=== for文による二次元配列のループ ===
1 2 3
4 5 6
7 8 9
=== 拡張for文による二次元配列のループ ===
1 2 3
4 5 6
7 8 9
配列の全要素の合計: 45
二次元配列では、外側のループで各行を取得し、内側のループで行内の各要素を処理します。拡張for文を使う場合、外側のループでは行全体が配列として取得され、内側のループで個々の要素を処理します。
7. 配列のループ処理における注意点
配列のループ処理を行う際には、いくつかの注意点があります。これらを理解しておくことで、バグを防ぎ、より安全なコードを書くことができます。
for文やwhile文でインデックスを使う場合、配列の範囲を超えてアクセスしないように注意が必要です。条件式はi < array.lengthとし、i <= array.lengthとしないようにしましょう。配列のインデックスは0から始まり、最後の要素はlength - 1です。
拡張for文で取得した変数は、配列要素のコピーです。そのため、変数の値を変更しても、元の配列には反映されません。配列の要素を変更したい場合は、通常のfor文を使ってインデックスで直接アクセスする必要があります。
配列がnullの場合、ループを実行するとエラーが発生します。ループの前に、配列がnullでないことを確認するとより安全です。また、要素数が0の空配列の場合、ループは一度も実行されずに終了します。
特に初心者の方は、インデックスの範囲外エラーに注意してください。このエラーは実行時に発生するため、コンパイル時には検出されません。デバッグの際には、配列のサイズとループの条件を確認することが重要です。
8. ループ制御文の活用
配列のループ処理では、break文やcontinue文を使ってループの流れを制御できます。これらの制御文を適切に使うことで、より効率的で読みやすいコードを書くことができます。
break文は、ループを途中で終了させるために使います。特定の条件を満たした時点でループを抜けたい場合に便利です。一方、continue文は、現在の反復をスキップして次の反復に進むために使います。
| 制御文 | 動作 | 使用例 |
|---|---|---|
break |
ループを完全に終了する | 目的の要素が見つかった時点でループを抜ける |
continue |
現在の反復をスキップして次へ | 特定の条件の要素だけ処理をスキップする |
例えば、配列から特定の値を探す場合、見つかった時点でbreak文でループを終了すれば、無駄な処理を省けます。また、配列内の特定の値だけを除外して処理したい場合は、continue文を使って該当する要素の処理をスキップできます。
ただし、break文やcontinue文を多用すると、コードの流れが複雑になり可読性が低下する場合があります。適切な場面で使用することが大切です。
9. パフォーマンスの考慮
配列のループ処理では、パフォーマンスも考慮する必要があります。特に大量のデータを扱う場合、ループの書き方によって処理速度に差が出ることがあります。
一般的に、拡張for文と通常のfor文のパフォーマンスはほぼ同じです。ただし、ループ内で配列のlengthプロパティに何度もアクセスすると、わずかにパフォーマンスが低下する可能性があります。そのため、ループの条件式でlengthを直接使うのではなく、事前に変数に格納しておく方法もあります。
しかし、現代のJava仮想マシンは非常に最適化されているため、通常の使用ではこのような細かい最適化を気にする必要はありません。むしろ、コードの可読性と保守性を優先すべきです。パフォーマンスが重要な場面では、実際に計測してボトルネックを特定してから最適化を行うことをおすすめします。
配列のループ処理で最も重要なのは、適切なループ方法を選択し、バグのない正確なコードを書くことです。可読性の高いコードは、チーム開発においても大きなメリットとなります。
10. 実践的な配列ループの例
最後に、実践的な配列ループの例をいくつか紹介します。これらの例を参考に、実際のプログラミングで配列のループを活用してください。
配列の最大値や最小値を見つける処理、配列の要素を条件でフィルタリングする処理、複数の配列を組み合わせる処理など、実務でよく使われるパターンを学ぶことで、配列のループ処理への理解が深まります。
public class PracticalArrayLoopExamples {
public static void main(String[] args) {
int[] numbers = {45, 23, 67, 12, 89, 34, 56};
// 配列の最大値を見つける
int max = numbers[0];
for (int num : numbers) {
if (num > max) {
max = num;
}
}
System.out.println("最大値: " + max);
// 配列の最小値を見つける
int min = numbers[0];
for (int num : numbers) {
if (num < min) {
min = num;
}
}
System.out.println("最小値: " + min);
// 偶数だけを抽出してカウント
int evenCount = 0;
System.out.print("偶数: ");
for (int num : numbers) {
if (num % 2 == 0) {
System.out.print(num + " ");
evenCount++;
}
}
System.out.println("\n偶数の個数: " + evenCount);
// 配列を逆順に表示
System.out.print("逆順: ");
for (int i = numbers.length - 1; i >= 0; i--) {
System.out.print(numbers[i] + " ");
}
System.out.println();
}
}
最大値: 89
最小値: 12
偶数: 12 34 56
偶数の個数: 3
逆順: 56 34 89 12 67 23 45
この例では、配列から最大値と最小値を見つけたり、特定の条件を満たす要素だけを抽出したり、配列を逆順に処理したりしています。これらは実際のプログラミングでよく使われるパターンです。
配列のループ処理をマスターすることで、データの集計や検索、変換など、さまざまな処理を効率的に実装できるようになります。まずは基本的なfor文と拡張for文をしっかり理解し、状況に応じて適切なループ方法を選択できるようになりましょう。
まとめ
Javaの配列のループ処理は、プログラミングの基本でありながら、実務でも頻繁に利用される重要な技術です。本記事では、for文、拡張for文、while文という三つのループ方法について、それぞれの特徴と使い分けを丁寧に確認してきました。ここで改めて振り返ることで、知識をしっかり定着させていきましょう。
まず、for文はインデックスを使って配列の要素にアクセスする最も基本的なループ構文です。配列の何番目の要素を扱っているのかを明確にできるため、要素の書き換えや逆順処理、条件付きの細かい制御などに非常に適しています。特に配列の操作を細かく制御したい場合には、for文が最も柔軟に対応できる方法です。
次に、拡張for文は配列の全要素を順番に処理する場合に非常に便利です。コードが簡潔で読みやすく、初心者でも扱いやすい点が大きな特徴です。インデックスを意識せずに記述できるため、配列の読み取り処理では最も推奨される書き方といえます。ただし、要素の変更やインデックスが必要な処理には向いていないため、用途を理解して使い分けることが重要です。
while文は条件に応じてループを継続する構文であり、ループ回数が事前に分からない場合や、特定の条件で途中終了したい場合に適しています。配列処理ではやや使用頻度は低いものの、break文と組み合わせることで柔軟な処理が可能になります。実務では、データ検索や条件判定を伴う処理で活用されることが多いです。
また、多次元配列のループ処理では、ループの入れ子構造を理解することが重要です。二次元配列では外側のループで行を、内側のループで列を処理するという基本パターンを覚えておくことで、表形式のデータもスムーズに扱えるようになります。
配列のループ処理においては、インデックスの範囲外エラーやnullチェックなどの注意点も重要です。特に初学者は、条件式を誤って配列の範囲を超えてしまうミスが多いため、lengthを正しく使うことを意識しましょう。また、拡張for文では値の変更が元の配列に反映されない点も押さえておく必要があります。
実務では、配列のループ処理を使って、データの集計、検索、フィルタリング、変換などさまざまな処理を行います。最大値や最小値の取得、条件に一致する要素の抽出などは、基本的でありながら非常に重要なパターンです。これらを確実に理解することで、プログラミングの応用力が大きく向上します。
最後に、可読性と保守性を意識したコードを書くことも忘れてはいけません。単に動くコードではなく、他の人が読んでも理解しやすいコードを書くことが、良いエンジニアへの第一歩です。状況に応じて適切なループ構文を選択し、シンプルで分かりやすい処理を心がけていきましょう。
まとめのサンプルプログラム
public class LoopSummaryExample {
public static void main(String[] args) {
int[] data = {5, 10, 15, 20, 25};
// for文
for (int i = 0; i < data.length; i++) {
System.out.println("for文: " + data[i]);
}
// 拡張for文
for (int value : data) {
System.out.println("拡張for文: " + value);
}
// while文
int index = 0;
while (index < data.length) {
System.out.println("while文: " + data[index]);
index++;
}
}
}
生徒
配列のループって、こんなに種類があるとは思いませんでした。でも、それぞれ役割が違うんですね。
先生
そうですね。大切なのは、どの場面でどのループを使うべきかを判断できることです。例えば、インデックスが必要ならfor文、単純な繰り返しなら拡張for文というように使い分けます。
生徒
while文は少し難しく感じましたが、条件で止められるのは便利そうですね。
先生
その通りです。特にデータ検索などではとても役立ちます。break文と一緒に使うと、効率的な処理ができますよ。
生徒
実務ではどれを一番使いますか。
先生
用途によりますが、読み取りだけなら拡張for文が多いですね。ただし、細かい制御が必要な場合はfor文を使います。どちらも使いこなせることが大切です。
生徒
まずは基本をしっかり練習して、使い分けできるように頑張ります。
先生
その姿勢が大切です。配列とループは基礎ですが、応用範囲が広いので、しっかり身につけていきましょう。