List.of()メソッドとは? Java初心者の勉強

2020-12-02

Java SE9からList.of()メソッドが登場しました。
気になるのでまとめたいと思います。

List.of()メソッドとは

List.of()メソッドは簡単に変更が不可能(unmodifiable)なリストを作成することができます。
List.of()にはわかりやすく2つの特徴があります。(他にもあるようですが飛ばします。)

  • nullは許容しない
  • unmodifiable(変更不可)である(追加・削除・置換はできない)
  • リスト内の要素の順序は、引数の順序、または指定された配列内の要素の順序と同じです(並び替え不可)
  • value-basedである

List.of()を使ってみる!

List.of()メソッドは引数なしの形から1-10個までの引数、と可変長引数の12個があります。全部紹介するのも長ったらしいのでList.of()がどんなものかサンプルコードを交えて紹介していきます。

※ import java.util.*; で実験しています。

List.of() 引数なしのサンプルコード

nullを許容しないList.of()ですが、「List.of()」はどんなリストを作成するのでしょうか。

// 0個の要素を含んだ不変のリストが作成されます。
List list = List.of();
System.out.print(list); // []

使い道がよくわかりませんが。コンパイルエラーや実行時エラーになることはありません。

List.of() 引数ありのサンプルコード

引数ありのList.of()を使ってみます。

// List.of()でリストを作成
List list = List.of(1,2,3);
System.out.print(list); // [1, 2, 3]

// ArrayList()との比較
List list = new ArrayList<>();
list.add("Hello");
list.add("Program");
list.add("Life");
System.out.print(list); // [Hello, Program, Life]

List.ofを使えば瞬時にListへ値を挿入できます。

List.of() 引数に変数のサンプルコード

変数をいれてみます。

Integer[] array1 = {1,2,3};
List list = List.of(array1);
System.out.println(list); // [1, 2, 3]

並び順は変数と同じで固定されます。

List.of()異なる型のサンプルコード

異なる型を引数に入れるとどうなるでしょう。

List list = List.of(1,"Hello",3.5, 'a');
System.out.print(list); // [1, Hello, 3.5, a]

混在することが可能です。

不変であるの検証

List arrayList1 = List.of(1,2,3);
arrayList1.add(4); // java.lang.UnsupportedOperationException

// おまけ
List arrayList2 = new ArrayList(List.of(1,2,3));
arrayList2.add(4);
System.out.println(arrayList2); //[1, 2, 3, 4]

List.of()はunmodifiable(変更不可)なのでadd()で値を追加しようとすると実行時エラーとなります。
おまけ:new ArrayList()内でList.of()をしてあげると変更可能です。初期値を設定する際にadd()で値を入れなくていいので便利です。

並べ替えはできない検証

並べ替えはできないようなので実験。

List<Integer> list = List.of(5,2,6,4,3,1);
Collections.sort(list); // UnsupportedOperationException

実行時エラーとなりました。

インスタンスの検証 (value-based)

List list1 = List.of(1,2,3);
List list2 = List.of(1,2,3);
System.out.println(list1 == list2); // false
System.out.println(list1.equals(list2)); // true
list1 = list2;
System.out.println(list1 == list2); // true

value-based聞いたことなかったですが、value-basedのものは、x.equals(y)で比較することで値が同等とみなされるようです。

Arrays.asList()との違い

上記のおさらいもかねて、よく比較しているのを見かけるのでついでに。

変更可能と不可

List.of()は変更不可(unmodifiable) のリストなので1度決めた値を変更することはできません。
Arrays.asList()は変更可能です。

サンプルコード

// Arrays.asList()の場合
List<String> list1 = Arrays.asList("1","2");
list1.set(0,"5"); // 変更可能

// List.of()の場合
List<String> list2 =List.of("1","2");
list2.set(0,"5"); // 実行時エラー (UnsupportedOperationException) 不変のため使えない

nullの許容

List.of()はnullを許容することはできませんが、Arrays.asList()はnullも許容します。

サンプルコード

// Arrays.asList()の場合
List list1= Arrays.asList(1, 2, null); // nullを許容

// List.of()の場合
List list2 = List.of(1, 2, null); // 実行時エラー (NullPointerException) nullを許容しない

contains(null)での違い

// Arrays.asList()の場合
List list1 = Arrays.asList(1, 2, 3);
System.out.println(list1.contains(null)); // false

// List.of()の場合
List list2 = List.of(1, 2, 3);
System.out.println(list2.contains(1)); // true
list2.contains(null); // 実行時エラー (NullPointerException)

値の参照

// Arrays.asList()の場合
Integer[] array = {1,2,3};
List list = Arrays.asList(array);
array[1] = 10; System.out.println(list); // [1, 10, 3] arrayと共通の値を参照

// List.of()の場合
Integer[] array = {1,2,3};
List list = List.of(array);
array[1] = 10;
System.out.println(list); // [1, 2, 3] arrayと異なる値を参照

おわり

List.of()を使うと予期せず値を変更されたりせずに便利そうですね。
List.of()以外にもSet.of()とかあってシリーズもなんですかね。今回は力尽きたので深追いしませんでしたが、どこかで調べたいと思います。

参考

Java 9 Factory Methods
What is the difference between List.of and Arrays.asList?
https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/List.html

Java

Posted by Nakamoto