5.

Java 配列完全ガイド — 宣言/初期化/多次元/Arrays/Stream/ArrayList との違い

編集
この記事の要点
  • Java の配列は固定長。宣言時にサイズを指定し、後から長さを変えられない
  • 宣言: int[] arr = new int[10]; / 初期化子: int[] arr = {1, 2, 3}; / 多次元: int[][] m = new int[3][4];
  • 長さはプロパティ arr.length (メソッドではない)。インデックスは 0 始まり。範囲外は ArrayIndexOutOfBoundsException
  • Arrays クラス: sort / copyOf / fill / equals / toString / streamSystem.arraycopy は高速コピー
  • 配列 vs ArrayList: サイズ可変なら ArrayList、プリミティブ大量 (1 M 要素以上) や数値演算なら配列が高速・省メモリ

Java 配列の基本

Java の配列 (array) は同じ型の値を固定長で並べたデータ構造です。サイズはインスタンス化時に決定し、後から変更できません (拡張したい場合は ArrayListArrays.copyOf で新規配列を作る)。

// 宣言と確保
int[] arr = new int[10];               // 全要素 0 で初期化
double[] prices = new double[5];        // 全要素 0.0
boolean[] flags = new boolean[3];       // 全要素 false
String[] names = new String[4];         // 全要素 null (参照型)

// 初期化子による宣言
int[] primes = {2, 3, 5, 7, 11};
String[] colors = {"red", "green", "blue"};

// new で初期化子 (引数 / フィールドに代入する場合)
int[] data = new int[]{10, 20, 30};

// 長さ
System.out.println(primes.length);     // 5

// アクセス
primes[0] = 1;                          // 書き込み
int x = primes[2];                      // 読み込み (= 5)
// primes[10] ← ArrayIndexOutOfBoundsException

多次元配列

Java の多次元配列は厳密には「配列の配列」です。各行のサイズを変えられる不均一配列 (Jagged Array) も作れます。

// 3 行 4 列の二次元配列
int[][] matrix = new int[3][4];
matrix[0][0] = 1;
matrix[2][3] = 9;

// 初期化子
int[][] m = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
};

// 行ごとに長さが違う Jagged Array
int[][] jagged = new int[3][];
jagged[0] = new int[]{1};
jagged[1] = new int[]{1, 2};
jagged[2] = new int[]{1, 2, 3};

// 走査
for (int i = 0; i < m.length; i++) {
    for (int j = 0; j < m[i].length; j++) {
        System.out.print(m[i][j] + " ");
    }
    System.out.println();
}

// 3 次元以上もできる
int[][][] cube = new int[2][3][4];

拡張 for 文 (for-each)

int[] nums = {1, 2, 3, 4, 5};

// インデックス使わない
for (int n : nums) {
    System.out.println(n);
}

// 二次元配列
int[][] m = {{1, 2}, {3, 4}};
for (int[] row : m) {
    for (int x : row) {
        System.out.print(x + " ");
    }
}

// インデックスが必要なら従来形式
for (int i = 0; i < nums.length; i++) {
    System.out.println(i + ": " + nums[i]);
}

Arrays クラスの主要メソッド

配列操作のヘルパは java.util.Arrays に集約されています。

import java.util.Arrays;

int[] arr = {3, 1, 4, 1, 5, 9, 2, 6};

// ソート
Arrays.sort(arr);                        // {1,1,2,3,4,5,6,9} (in-place)

// 範囲ソート
Arrays.sort(arr, 0, 4);                  // [0,4) のみソート

// 二分探索 (要ソート済み)
int idx = Arrays.binarySearch(arr, 5);   // 該当インデックス

// 文字列化
System.out.println(Arrays.toString(arr)); // [1, 1, 2, 3, 4, 5, 6, 9]
int[][] m = {{1,2},{3,4}};
System.out.println(Arrays.deepToString(m));// [[1, 2], [3, 4]]

// 等価判定 (中身比較)
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b);              // false (参照比較)
System.out.println(Arrays.equals(a, b)); // true  (中身比較)

// 全要素埋め
int[] zeros = new int[10];
Arrays.fill(zeros, -1);                  // 全要素 -1

// 範囲指定 fill
Arrays.fill(zeros, 0, 5, 99);            // [0,5) のみ 99

// コピー
int[] copy = Arrays.copyOf(arr, 4);       // 先頭 4 要素
int[] sub  = Arrays.copyOfRange(arr, 2, 5); // [2,5)

// Stream への変換
int sum = Arrays.stream(arr).sum();
int max = Arrays.stream(arr).max().getAsInt();
double avg = Arrays.stream(arr).average().getAsDouble();

// List 化 (参照型のみ。プリミティブは boxed が必要)
String[] strs = {"a", "b", "c"};
List<String> list = Arrays.asList(strs); // 固定長 List (add 不可)

System.arraycopy で高速コピー

System.arraycopy はネイティブ実装で標準ループより圧倒的に高速。大きな配列のコピーや、ArrayList の内部実装でも利用されています。

int[] src  = {1, 2, 3, 4, 5};
int[] dest = new int[5];

// System.arraycopy(src, srcPos, dest, destPos, length)
System.arraycopy(src, 0, dest, 0, src.length);

// 部分コピー: src の [1,4) を dest の [2,5) へ
System.arraycopy(src, 1, dest, 2, 3);
// dest = [0, 0, 2, 3, 4]

配列 vs ArrayList

観点配列 (int[])ArrayList (List<Integer>)
サイズ固定 (作成時決定)可変 (自動拡張)
プリミティブ対応○ (int[] 直接)× (Integer にボクシング)
メモリ効率◎ (連続領域)△ (オブジェクト参照分のオーバーヘッド)
要素アクセスO(1)O(1)
末尾追加不可 (新配列で再作成)O(1) 償却
途中挿入/削除O(n) 手動O(n) add(i, e) / remove(i)
長さarr.length プロパティlist.size() メソッド
API少ない (Arrays クラス併用)豊富 (stream / sort / contains)

使い分けの目安:

  • サイズが事前に決まっていて変わらない → 配列
  • 数値計算・画像処理・ゲームループなど性能クリティカル → プリミティブ配列
  • 要素を動的に増減する → ArrayList
  • API の柔軟性・読みやすさ重視 → ArrayList

配列 ⇔ List 相互変換

import java.util.*;
import java.util.stream.*;

// 配列 → List
String[] arr = {"a", "b", "c"};
List<String> list1 = Arrays.asList(arr);         // 固定長 (add 不可)
List<String> list2 = new ArrayList<>(Arrays.asList(arr));  // 可変
List<String> list3 = Arrays.stream(arr).collect(Collectors.toList());

// List → 配列
String[] arr1 = list2.toArray(new String[0]);    // 推奨形式 (Java 8 以降)
String[] arr2 = list2.toArray(String[]::new);    // Java 11+

// プリミティブ配列 ↔ List<Integer>
int[] ints = {1, 2, 3};
List<Integer> boxed = Arrays.stream(ints).boxed().collect(Collectors.toList());
int[] back = boxed.stream().mapToInt(Integer::intValue).toArray();

FAQ

Q: 配列のサイズを後から変えたい
A: できません。Arrays.copyOf(arr, newSize) で新しい配列を作るか、ArrayList に切り替えてください。

Q: 配列に contains はある?
A: 配列自体にはありません。Arrays.asList(arr).contains(x) または Arrays.stream(arr).anyMatch(v -> v == x) を使います。

Q: 多次元配列で全要素を 0 にリセットしたい
A: for (int[] row : matrix) Arrays.fill(row, 0); のように行単位で fill します。Jagged Array でも同じです。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. データ型
  3. 変数
  4. 定数
  5. 配列
  6. コレクション(List,Set,Queue)
  7. Map(連想配列)
  8. 演算子
  9. 条件分岐
  10. 繰り返し制御文
  11. クラス
  12. メソッド
  13. インスタンス化
  14. コンストラクタ
  15. staticキーワード
  16. オーバーロード
  17. 継承
  18. オーバーライド
  19. this
  20. super
  21. パッケージ
  22. アクセス修飾子
  23. 抽象クラス・メソッド
  24. インターフェース
  25. カプセル化
  26. データベース接続
  27. セッション
  28. ファイル入出力
  29. ラムダ式

最近更新/作成されたページ