Arrays.asListとList.of
はじめに
Listを作成する際に使用する、Arrays.asListとList.ofの違いやどちらを選択すればいいのかが曖昧だったため調査、整理を行いました。
誤りがありましたらコメントいただけますと幸いです。
想定読者
Java初学者
Arrays.asListとは
- 配列を操作するためのArraysクラスで定義されているasListメソッド。
- 可変のリスト(mutable)を返す。
- リストの仮面を被った配列。
List.ofとは
- Java9で追加された、Listクラスのofメソッド。
- 不変のリスト(immutable)を返す。
- 作成時には、新しくリストが作成される。
と上記のように、違いを並べてもイメージがつかないので実際にコードを実行して確認してみる。
コードを書いて確認
変数型の違い
// varはオブジェクトから型を推論してくれる
var asList = Arrays.asList("A", "B", "C");
var of = List.of("A", "B", "C");
System.out.println(asList.getClass());
// 出力結果:class java.util.Arrays$ArrayList
System.out.println(of.getClass());
// 出力結果:class java.util.ImmutableCollections$ListN
代入した変数の型クラスを確認してみると、
asListはArrays$ArrayList
ofはImmutableCollections$ListN
となっている。
$の後ろは、インナークラスと呼ばれるクラスの中にあるクラスらしい。
要するに、asListはArrays型でofはImmutableCollections型で作成されている。
値の変更
asList.set(0, "D");
System.out.println(asList);
// 出力結果:[D, B, C]
of.set(0, "D"); // この時点でUnsupportedOperationExceptionの実行エラーが出る
System.out.println(of);
先ほど代入した変数の値を変更(set)してみる。
asListは裏側は配列のため、値を変更することができる。
ofは不変コレクションのため変更することができない。
値の追加
asList.add("E"); // UnsupportedOperationExceptionの実行エラー
of.add("E"); // UnsupportedOperationExceptionの実行エラー
今度は値を追加(add)してみる。
追加はどちらも実行エラーが発生した。
配列を使用してリストの初期化
// 配列を初期化しリストを作成する。
String[] strArray = { "A", "B", "C" };
var asList = Arrays.asList(strArray);
var of = List.of(strArray);
// 配列の変更前
System.out.println(Arrays.asList(strArray)); // 出力結果:[A, B, C]
System.out.println(asList); // 出力結果:[A, B, C]
System.out.println(of); // 出力結果:[A, B, C]
// 配列の値を変更
strArray[0] = "D";
// 配列の変更後
System.out.println(Arrays.asList(strArray)); // 出力結果:[D, B, C]
System.out.println(asList); // 出力結果:[D, B, C]
System.out.println(of); // 出力結果:[A, B, C]
まず配列strArrayを用意し、そのstrArrayを使いそれぞれリストを作成した。
そして、strArrayのインデックス0の値を変更し値の中身を確認してみる。
asListは、配列の変更が反映されていて値がAからDに変わっている。
一方ofは変更前と変わらずAのままになっている。
結果からも分かる通りArrays.asListは配列がリストのお面を被っただけで、新しくリストが作成されているわけでなはい。配列の参照を保持するリストを返している。
List.ofはリストを作成しているため、初期化時の配列の値を変更しても影響はない。
違いの比較
それぞれをまとめると以下のようになる。
Arrays.asList | List.of | |
---|---|---|
型 | Arrays$ArrayList | ImmutableCollections$ListN |
リスト作成時 | 配列の参照を保持するリストを返す。 | 新しくリストが作成される。 |
値の変更 | 可 | 不可 |
値の追加・削除 | 不可 | 不可 |
初期化時の配列の変更 | 影響する | 影響しない |
基本ArrayListなどを使うことが多そうなので、直接これらを使うことはなさそうだが仕様を理解しておくことで、何かの際に引き出しになればいいなと思います。
参考文献
Discussion