こんにちは、かつコーチです。
配列の基本を理解したら、次に出てくるのが多次元配列(配列の中にさらに配列を格納したデータ構造)です。
表形式のデータやマス目状のデータを扱う場面でよく登場します。
この記事では2次元配列を中心に、宣言方法・走査方法・ハマりやすいポイントを解説します。
多次元配列とは?
なぜ多次元配列が必要なのか
例えば「3クラス分、各クラス5人分のテストの点数」を扱いたいとき、1次元配列だけでは表現しづらくなります。
このような表形式・グリッド状のデータを表すために、配列の中に配列を入れる多次元配列を使います。
Javaの多次元配列は「配列の配列」
Javaの2次元配列は、厳密には「配列を要素として持つ配列」です。
言い換えると、各行の配列は独立しており、行ごとに異なる要素数を持たせることもできます。
これをジャグ配列(各行の長さが揃っていない配列)と呼びます。
基本の書き方:2次元配列
2次元配列の宣言と初期化
public class Main {
public static void main(String[] args) {
// 3クラス分、各クラス3人分の点数
int[][] scores = {
{80, 90, 70},
{60, 75, 85},
{95, 88, 92}
};
System.out.println(scores[0][1]); // 1クラス目の2人目 -> 90
System.out.println(scores[2][0]); // 3クラス目の1人目 -> 95
}
}
scores[行][列]のように2つの添字を指定してアクセスします。
行方向がクラス、列方向が生徒番号、というように意味を決めて設計すると読みやすくなります。
newを使った2次元配列の作成
int[][] grid = new int[3][4]; // 3行4列の配列(すべて0で初期化される)
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = i * 4 + j;
}
}
grid.lengthは行数、grid[i].lengthはi行目の列数を表します。
2次元配列を走査するときは、この2つのlengthを組み合わせて二重のfor文を書くのが基本パターンです。
よくあるつまずきポイント・エラー対処
添字の順番を取り違えたハマりどころ
私が実際に手を動かしたときにやってしまったミスがこちらです。
❌ Before
int[][] scores = {
{80, 90, 70},
{60, 75, 85}
};
// 「1人目の2クラス分の点数」のつもりで書いたが実際は逆
System.out.println(scores[1][0]);
「1人目、2クラス目」のつもりでscores[1][0]と書きましたが、実際には「2クラス目の1人目」という意味になり、想定と異なる値を取得していました。
2次元配列は「外側が行、内側が列」という順序を常に意識しないと、意図と逆の要素を読んでしまいます。
✅ After
// 変数名で行・列の意味を明示しておくと間違えにくい
int classIndex = 1; // 2クラス目
int studentIndex = 0; // 1人目
System.out.println(scores[classIndex][studentIndex]);
添字をそのまま数字で書くのではなく、意味の分かる変数名に置き換えることで、どちらが行でどちらが列かを混同しにくくなります。
行ごとに列数が異なるジャグ配列でのNullPointerException
❌ Before
int[][] jagged = new int[3][];
jagged[0] = new int[]{1, 2, 3};
jagged[1] = new int[]{4, 5};
// jagged[2] を初期化し忘れる
for (int[] row : jagged) {
for (int value : row) { // NullPointerException
System.out.println(value);
}
}
new int[3][]で作った時点では、各行はまだnullのままです。jagged[2]を初期化せずに走査しようとすると、rowがnullとなりNullPointerExceptionが発生します。
✅ After
int[][] jagged = new int[3][];
jagged[0] = new int[]{1, 2, 3};
jagged[1] = new int[]{4, 5};
jagged[2] = new int[]{6};
for (int[] row : jagged) {
for (int value : row) {
System.out.println(value);
}
}
行ごとに長さが異なる配列を使う場合は、すべての行を初期化し終えたかを必ず確認しましょう。
応用・一歩先の使い方
Arrays.deepToStringで多次元配列を確認する
import java.util.Arrays;
int[][] scores = {
{80, 90, 70},
{60, 75, 85}
};
System.out.println(Arrays.deepToString(scores));
// [[80, 90, 70], [60, 75, 85]]
1次元配列ではArrays.toStringを使いましたが、多次元配列の中身を表示したい場合はArrays.deepToStringを使います。toStringだと内側の配列がハッシュ値の羅列になってしまうため、デバッグ時にはこちらを使い分けましょう。
まとめ
この記事のポイント
- Javaの2次元配列は「配列を要素に持つ配列」で、行ごとに要素数を変えることもできる
array[行][列]の順序を混同すると意図と逆の要素を取得してしまう- ジャグ配列は行ごとの初期化漏れがNullPointerExceptionの原因になりやすい
- 多次元配列の中身の確認には
Arrays.deepToStringを使う
次に読むべき記事
- 配列の基本:宣言・初期化・要素アクセス
- Stringの基本:作成・比較・連結
タグ: Java, 中級者向け, 基本文法