多次元配列と List<List<T>> の使い分け — 可変性と利便性
Java では「二次元以上のデータ構造」を表す方法が大きく分けて2つあります。
- 多次元配列(int[][], String[][] など)
- 入れ子のリスト(List<List<T>>)
どちらも「表形式のデータ」を扱えますが、可変性・柔軟性・利便性に違いがあります。初心者向けに整理してみましょう。
多次元配列の特徴
- 固定サイズ: 宣言時に行・列のサイズを決める。後から伸縮できない。
- 高速アクセス: インデックスで直接アクセスできるため、処理速度は速い。
- メモリ効率: プリミティブ型配列はオーバーヘッドが少なく効率的。
- 用途: 行列計算、画像処理など「サイズが決まっていて数値演算中心」の場面。
基本コード例
int[][] matrix = new int[3][4]; // 3行4列
matrix[0][0] = 1;
matrix[2][3] = 99;
System.out.println(matrix[2][3]); // 99
JavaList<List<T>> の特徴
- 可変サイズ: 行数・列数を後から追加・削除できる。
- 柔軟性: 行ごとに列数が違ってもよい(ジャグ配列的)。
- 便利メソッド:
add,remove,containsなどコレクション API が使える。 - 用途: 動的に増減する表、テキスト処理、柔軟なデータ構造。
基本コード例
import java.util.*;
List<List<String>> table = new ArrayList<>();
// 行追加
table.add(new ArrayList<>(List.of("A","B")));
table.add(new ArrayList<>(List.of("C","D","E")));
// 要素アクセス
System.out.println(table.get(1).get(2)); // "E"
// 要素追加
table.get(0).add("X"); // 1行目に列追加
System.out.println(table); // [[A, B, X], [C, D, E]]
Java例題で理解する
例題1: 固定サイズの成績表(配列)
int[][] scores = {
{80, 90, 70},
{60, 75, 85},
{100, 95, 90}
};
System.out.println(scores[2][1]); // 95
Java- 用途: 生徒×科目の固定表。サイズが決まっているので配列で十分。
例題2: 可変サイズの出席簿(List<List>)
List<List<String>> attendance = new ArrayList<>();
attendance.add(new ArrayList<>(List.of("Alice","Bob"))); // 1日目
attendance.add(new ArrayList<>(List.of("Cara"))); // 2日目
attendance.get(1).add("Dan"); // 2日目に追加
System.out.println(attendance); // [[Alice, Bob], [Cara, Dan]]
Java- 用途: 日ごとに人数が変わる出席簿。柔軟に追加できる。
例題3: ジャグ配列 vs List の違い
// ジャグ配列
int[][] jagged = new int[2][];
jagged[0] = new int[]{1,2};
jagged[1] = new int[]{3,4,5};
// List版
List<List<Integer>> jaggedList = new ArrayList<>();
jaggedList.add(new ArrayList<>(List.of(1,2)));
jaggedList.add(new ArrayList<>(List.of(3,4,5)));
Java- ポイント: 配列でも「行ごとに列数が違う」ジャグ配列は作れるが、List の方が追加・削除が簡単。
テンプレート集
- 固定行列(配列)
T[][] matrix = new T[rows][cols];
matrix[r][c] = value;
Java- 動的表(List)
List<List<T>> table = new ArrayList<>();
table.add(new ArrayList<>()); // 行追加
table.get(row).add(value); // 列追加
Java- ジャグ構造(配列版)
int[][] jagged = new int[rows][];
jagged[0] = new int[]{...};
Java- ジャグ構造(List版)
List<List<T>> jagged = new ArrayList<>();
jagged.add(new ArrayList<>(List.of(...)));
Java使い分けの指針
- 配列を選ぶ:
- サイズが固定
- 数値演算中心(行列計算、画像処理)
- メモリ効率・速度重視
- List<List> を選ぶ:
- サイズが可変
- 行ごとに列数が違う
- コレクション API を活用したい
- データの追加・削除が頻繁
まとめ
- 多次元配列: 高速・効率的だが固定サイズ。数値演算や行列に向く。
- List<List>: 柔軟・便利だがオーバーヘッドあり。動的な表や可変データに向く。
- 選び方: 「固定か可変か」「演算中心か操作中心か」で判断すると迷わない。
👉 練習課題: 「3×3 の配列で行列計算」と「日ごとに人数が変わる出席簿」をそれぞれ配列と List で書いてみると違いが体感できます。
