Java : 配列からListへの変換
本記事では、配列から List へ変換する方法を3つご紹介します。
よく使われる Arrays.asList メソッドの注意点についても解説します。
概要
Java では、同じ型の複数の要素(値) を管理する方法として、配列 と List があります。
// 配列
final String[] array = {"aaa", "bbb", "ccc"};
// リスト
final var list = List.of("xxx", "yyy", "zzz");
この配列と List ですが、
- 配列 → List
- List → 配列
と相互に変換したくなることが、たまにあったります。
本記事では、配列から List への変換にしぼって、3つの方法をご紹介します。
List から配列への変換については、下記の関連記事をご参照ください。
関連記事
配列からリストへの変換
簡単なまとめ
変換方法 | おすすめ度 | 不変オブジェクト | サイズの変わる操作 | 要素の連動 |
---|---|---|---|---|
List.of | ☆☆☆ | 〇 | × | しない |
Arrays.asList | ☆ | × | × | する |
リストのコンストラクタで初期化 | ☆☆ | × | 〇 | しない |
関連記事
List.of メソッド
もし変換した List に対して変更が必要なければ、List.of メソッドを使うのがおすすめです。
List.of メソッドは、配列を 不変オブジェクト である List へと変換します。
文字列の配列 (String[]) を List<String> へ変換する例を見てみましょう。
// 文字列の配列
final String[] array = {"aaa", "bbb", "ccc"};
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
// リストへ変換
final List<String> list = List.of(array);
System.out.println(list); // [aaa, bbb, ccc]
変換した List は不変オブジェクトです。
そのため、List を変更しようとすると
- 非チェック例外 : UnsupportedOperationException
が発生します。
List の要素を変更する set メソッドを使う例です。
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = List.of(array);
System.out.println(list); // [aaa, bbb, ccc]
list.set(1, "XXX"); // UnsupportedOperationException 発生
配列と List は連動しません。
配列の要素を変更しても、List には反映されません。
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = List.of(array);
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
System.out.println(list); // [aaa, bbb, ccc]
// 配列の要素を変更
array[1] = "XXX";
System.out.println(Arrays.toString(array)); // [aaa, XXX, ccc]
System.out.println(list); // [aaa, bbb, ccc]
配列 array の要素だけが "XXX" に変更されたのが分かりますね。
list の要素は変更されていません。
Arrays.asList メソッド
Arrays クラスの asList メソッドを使う例です。
// 文字列の配列
final String[] array = {"aaa", "bbb", "ccc"};
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
// リストへ変換
final List<String> list = Arrays.asList(array);
System.out.println(list); // [aaa, bbb, ccc]
ただし、2つ注意点があります。
【 List に対してサイズが変わる操作はできない】
例えば、List の add メソッドで要素を追加しようとすると
- 非チェック例外 : UnsupportedOperationException
が発生します。
(add メソッドは List のサイズを +1 します)
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = Arrays.asList(array);
System.out.println(list); // [aaa, bbb, ccc]
list.add("XXX"); // UnsupportedOperationException 発生
List の remove メソッドで要素を削除する場合も同じです。
【配列と List が連動する】
配列で変更した内容が List にも反映されます。
また、List で変更した内容は配列にも反映されます。
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = Arrays.asList(array);
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
System.out.println(list); // [aaa, bbb, ccc]
// 配列の要素を変更
array[1] = "XXX";
System.out.println(Arrays.toString(array)); // [aaa, XXX, ccc]
System.out.println(list); // [aaa, XXX, ccc]
// リストの要素を変更
list.set(2, "YYY");
System.out.println(Arrays.toString(array)); // [aaa, XXX, YYY]
System.out.println(list); // [aaa, XXX, YYY]
array の要素を変更すると list の要素も変更されていることが分かりますね。
list の変更も array に反映されています。
これが意図どおりであればよいのですが、もし違うのであれば思わぬ不具合を発生させる … かもしれません。
このような理由から、Arrays.asList メソッドはあまりおすすめしません。
リストのコンストラクタで初期化
ArrayList クラスは List インタフェースの実装の1つです。
コンストラクタに Collection を指定すことで要素を初期化できます。
(ちなみに List は Collection のサブインタフェースです)
ひと手間かかりますが、
- Arrays.asList メソッドで、配列を List (Collection) へ変換
- その List (Collection) を使って、ArrayList を初期化
という手順で、より安全に List へ変換できます。
※今回は ArrayList を使いますが、他の実装 … 例えば LinkedList を使っても OK です。
// 文字列の配列
final String[] array = {"aaa", "bbb", "ccc"};
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
// リストへ変換
final List<String> list = new ArrayList<>(Arrays.asList(array));
System.out.println(list); // [aaa, bbb, ccc]
Arrays.asList メソッドと違い、List のサイズが変わる操作も OK です。
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = new ArrayList<>(Arrays.asList(array));
System.out.println(list); // [aaa, bbb, ccc]
// 要素の追加もOK!
list.add("XXX");
System.out.println(list); // [aaa, bbb, ccc, XXX]
さらに、配列と List は連動しません。
final String[] array = {"aaa", "bbb", "ccc"};
final List<String> list = new ArrayList<>(Arrays.asList(array));
System.out.println(Arrays.toString(array)); // [aaa, bbb, ccc]
System.out.println(list); // [aaa, bbb, ccc]
// 配列の要素を変更
array[1] = "XXX";
System.out.println(Arrays.toString(array)); // [aaa, XXX, ccc]
System.out.println(list); // [aaa, bbb, ccc]
// リストの要素を変更
list.set(2, "YYY");
System.out.println(Arrays.toString(array)); // [aaa, XXX, ccc]
System.out.println(list); // [aaa, bbb, YYY]
まとめ
本記事では、配列から List への変換方法を3つご紹介しました。
- 不変オブジェクトの List であれば … List.of
- 変更可能な List であれば … リストのコンストラクタで初期化
を使うのがおすすめです。
関連記事
- List(リスト)の基本
- Map(マップ)の基本
- Set(セット)の基本
- List の初期化方法いろいろ
- Map の初期化方法いろいろ
- Set の初期化方法いろいろ
- 配列 vs. List
- List から配列への変換
- API 使用例
- Collection (コレクション)
- Collections (コレクション操作)
- Comparable
- Comparator
- Iterator
- List (リスト)
- Map (マップ)
- Map.Entry (キーと値のペア)
- Queue (キュー)
- AbstractQueue
- ArrayBlockingQueue (ブロッキング・配列キュー)
- ArrayDeque (両端キュー)
- BlockingDeque (ブロッキング・両端キュー)
- BlockingQueue (ブロッキング・キュー)
- ConcurrentLinkedDeque (並列処理用・両端キュー)
- ConcurrentLinkedQueue (並列処理用キュー)
- Deque (両端キュー)
- LinkedBlockingDeque (ブロッキング・リンク両端キュー)
- LinkedBlockingQueue (ブロッキング・リンクキュー)
- LinkedList (二重リンク・リスト)
- PriorityBlockingQueue (ブロッキング・優先度付きキュー)
- PriorityQueue (優先度付きキュー)
- RandomAccess
- Set (セット)
- Spliterator