ぺんぎんらぼ

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です。たまに絵を描きます。

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です

JDK9で追加されたofメソッドについて

java
java

JDK8までは「Stream系APIの検証をしたく、仮のコレクションをいったん作成したい」
というとき、以下のように書いていました。

JDK8まで

// [1]StringからStream
Stream<String> streaml = Stream.of("A","B","C","D","E");

// [2]配列からStream
Stream<String> stream2 = Arrays.stream(new String[] {"A","B","C","D","E"});

// [3]ListからStream
Stream<String> stream3 = Arrays.asList("A","B","C","D","E").stream();

// [4]MapからStream
Map<String, Dto> map = new HashMap<String, Dto>() {
    {
        put("A", new Dto());
        put("B", new Dto());
        put("C", new Dto());
    }
};
Stream<Map.Entry<String, Dto>> stream4 = map.entrySet().stream();

[1]~[3]までは一行で書けるものの、[4]のmapは一つずつputしていて長くなってしまう。

そこで使えるのがJDK9で追加されたof()メソッド
[3]Listと[4]Mapも以下のように書けるようになりました。

JDK9以降

// [3]ListからStream
List<String> list = List.of("A", "B", "C");
Stream stream3 = list.stream();

// [4]MapからStream
Map<String, Dto> map
   = Map.of("A", new Dto(), "B", new Dto(), "C", new Dto());
Stream<Map.Entry<String, Dto>> stream4 = map.entrySet().stream();

ofメソッドの中身はどうなっているかというと以下。
MapがKeyとValueを交互に引数として受け取るようになってます。

// [3]List
    static <E> List<E> of(E e1, E e2, E e3) {
        return new ImmutableCollections.ListN<>(e1, e2, e3);
    }
// [4]Map
    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
        return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3);
    }

一つ注意点としては、上記の通り返却しているのがImmutableなクラスとなるので、取得したインスタンスの変更ができません。
この後に変更処理を書きたいという場合は、以下のように新しくインスタンスを生成しなおしてあげましょう。

修正前

// [3]
List<String> list = List.of("A", "B", "C");
list.add("D"); // UnsupportedOperationExceptionが発生

修正後

// [3]
List<String> list = new ArrayList<>(List.of("A", "B", "C"));

// [4]
Map<String, Dto> map = new HashMap<>(Map.of("A", new Dto(), "B", new Dto(), "C", new Dto()));

以上