Java Tips | コレクション:配列→List

Java Java
スポンサーリンク

配列→List変換は「生の配列を“扱いやすいコレクション”に変える」技

Java には「配列」と「List」という、よく似ているけれど性格の違う入れ物があります。
配列:String[] など。古くからある、サイズ固定の入れ物。
List:List<String> など。サイズ可変で、コレクションAPIが使える入れ物。

業務コードでは、
「古いライブラリやフレームワークから配列で返ってくる」
「自分たちの処理は List ベースで書きたい」
ということがよくあります。

そこで必要になるのが「配列→List変換」です。
“生の配列”を、“扱いやすい List” に変えるイメージを持ってください。


基本形1:Arrays.asList で配列を List にする

一番よく見る書き方

まずは、標準的な変換方法です。

import java.util.Arrays;
import java.util.List;

public class ArrayToListBasic {

    public static void main(String[] args) {
        String[] array = {"A", "B", "C"};

        List<String> list = Arrays.asList(array);

        System.out.println(list); // [A, B, C]
    }
}
Java

見た目はこれで十分に見えますが、ここで一番大事なのは
Arrays.asList が返す List の“性質”を正しく理解すること」です。

重要ポイント:サイズ固定&元配列と“連動”する

Arrays.asList(array) が返す List は、次のような特徴を持ちます。

サイズ固定(要素数を増やしたり減らしたりできない)。
元の配列と中身を共有している(片方を変えるともう片方も変わる)。

具体的に見てみます。

String[] array = {"A", "B", "C"};
List<String> list = Arrays.asList(array);

array[0] = "X";
System.out.println(list); // [X, B, C] に変わっている

list.set(1, "Y");
System.out.println(Arrays.toString(array)); // [X, Y, C]
Java

さらに、サイズを変えようとすると例外になります。

list.add("D");    // UnsupportedOperationException
list.remove(0);   // UnsupportedOperationException
Java

ここがとても重要です。
Arrays.asList の戻り値は“普通の ArrayList ではない”」ということを、必ず覚えておいてください。


基本形2:「完全に独立した可変List」が欲しい場合

new ArrayList<>(Arrays.asList(…)) のパターン

業務では、「あとで add/remove したい」「元の配列とは切り離したい」ことが多いです。
その場合は、こう書きます。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

String[] array = {"A", "B", "C"};

List<String> list = new ArrayList<>(Arrays.asList(array));

list.add("D"); // OK
System.out.println(list); // [A, B, C, D]

array[0] = "X";
System.out.println(list); // [A, B, C, D] のまま(連動しない)
Java

ここでの重要ポイントは二つです。

一つ目は、「new ArrayList<>(...) で“中身をコピーした、完全に独立した List”を作っている」ことです。
これにより、元配列と List の間に一切の連動がなくなります。

二つ目は、「業務コードでは“とりあえず配列→List”ではなく、“可変かどうか・連動させるかどうか”を意識して選ぶ」ことです。
ほとんどの場合、「可変で独立した List」が欲しいので、new ArrayList<>(Arrays.asList(...)) が定番パターンになります。


プリミティブ配列(int[] など)に注意

Arrays.asList(int[]) は「思った List にならない」

ここも初心者がかなりハマるポイントです。

int[] nums = {1, 2, 3};
List<int[]> list = Arrays.asList(nums);
System.out.println(list.size()); // 1
Java

「要素数 3 の List<Integer>」を期待したくなりますが、実際には
「要素数 1 の List<int[]>(配列が1個入っている)」になります。

理由は、Arrays.asList が「引数を可変長引数として受け取る」仕組みだからです。
int[] はオブジェクト1個として扱われてしまいます。

プリミティブ配列を List にしたい場合は、Stream を使うのが素直です。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

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

List<Integer> list =
        Arrays.stream(nums)      // IntStream
              .boxed()           // Integer にボクシング
              .collect(Collectors.toList());

System.out.println(list); // [1, 2, 3]
Java

ここでの重要ポイントは、
int[]long[] など“プリミティブ配列”は、Arrays.asList ではなく Arrays.stream(...).boxed() を使う」ことです。


ユーティリティ化して「意図を名前にする」

配列→List変換ユーティリティの例

毎回 new ArrayList<>(Arrays.asList(...))Arrays.stream(...).boxed() と書くのはうるさいので、
ユーティリティにまとめてしまうと読みやすくなります。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public final class ArrayLists {

    private ArrayLists() {}

    // 参照型配列 → 可変List
    public static <T> List<T> mutableListOf(T[] array) {
        if (array == null || array.length == 0) {
            return new ArrayList<>();
        }
        return new ArrayList<>(Arrays.asList(array));
    }

    // int[] → List<Integer>
    public static List<Integer> fromIntArray(int[] array) {
        if (array == null || array.length == 0) {
            return List.of();
        }
        return Arrays.stream(array)
                     .boxed()
                     .collect(Collectors.toList());
    }
}
Java

使い方はこうです。

String[] namesArray = {"山田", "佐藤"};
List<String> names = ArrayLists.mutableListOf(namesArray);

int[] scoresArray = {80, 90};
List<Integer> scores = ArrayLists.fromIntArray(scoresArray);
Java

ここでの重要ポイントは三つです。

一つ目は、「null や空配列の扱いをユーティリティ側で決めている」ことです。
呼び出し側は「とりあえず List が欲しい」とだけ考えればよく、毎回 null チェックを書かなくて済みます。

二つ目は、「mutableListOf という名前で、“可変Listを作る”意図をはっきりさせている」ことです。
Arrays.asList のような“サイズ固定List”とは違う、ということが名前から伝わります。

三つ目は、「プリミティブ配列用の変換も一箇所に閉じ込めている」ことです。
fromIntArray を使う側は、「プリミティブかどうか」を意識せずに List として扱えます。


まとめ:配列→List変換ユーティリティで身につけてほしい感覚

配列→List変換は、
単に「書き方を覚える」話ではなく、
「“生の配列”を、意図に合った List に変える設計」です。

Arrays.asList は「サイズ固定で、元配列と連動する List」を返すことを理解する。
業務ではたいてい「可変で独立した List」が欲しいので、new ArrayList<>(Arrays.asList(...)) を基本形にする。
プリミティブ配列(int[] など)は Arrays.stream(...).boxed()List<Integer> などに変換する。
よく使うパターンは ArrayLists.mutableListOf のようなユーティリティにまとめて、呼び出し側の意図をシンプルに書く。

あなたのコードのどこかに、
「配列のまま for 文でゴリゴリ回している」箇所があれば、
それを一度「配列→List変換+コレクションAPI」に置き換えられないか眺めてみてください。

その小さな変換が、
「データ構造を“扱いやすさ”から選べるエンジニア」への、
確かな一歩になります。

タイトルとURLをコピーしました