不変コレクションへのJavaストリームを集める

Javaストリームを不変のコレクションに収集する

1. 前書き

この簡単な記事では、JavaStreamsを不変のCollections –に収集するさまざまな方法を見ていきます。これは、標準のCollectorsが可変のデータ構造でのみ機能するため、特別なアプローチが必要です。

2. メーベン依存

GoogleのGuavaライブラリを利用して、いくつかの例を紹介します。


    com.google.guava
    guava
    22.0

この依存関係の最新バージョンはhereから取得できます。

3. JavaのcollectingAndThen()を使用する

JavaのCollectorsクラスのcollectingAndThen()メソッドは、Collectorと、Collector:から返された結果に適用されるfinisherFunctionを受け入れます。

@Test
public void whenUsingCollectingToImmutableList_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c");
    List result = givenList.stream()
      .collect(collectingAndThen(toList(), ImmutableList::copyOf));

    System.out.println(result.getClass());
}

toCollection() Collectorを直接,で使用することはできないため、要素を一時リストに収集し、そこから不変のリストを作成する必要があります。

この例では、toList()コレクターを使用してStreamListに変換してから、ImmutableListを作成しています。 ImmutableListはGuavaライブラリの一部です。 出力をコンソールに記録すると、基になるクラスのクラスが取得されます

出力をコンソールに記録すると、基になるList実装のクラスが取得されます。

class com.google.common.collect.RegularImmutableList

4. GuavaのCollectorsを使用する

Guava 21以降、すべての不変クラスには、標準のCollectors:と同じくらい簡単に使用できるCollectorが付属しています。

@Test
public void whenCollectToImmutableList_thenSuccess() {
    List list = IntStream.range(0, 9)
      .boxed()
      .collect(ImmutableList.toImmutableList());
}

結果のインスタンスはRegularImmutableListです。

class com.google.common.collect.RegularImmutableList

5. カスタムコレクターの構築

それでは、さらに一歩進んで、カスタムCollectorを実装しましょう。 この目標を達成するために、静的なCollector.of()メソッドを使用します。

public static  Collector, List> toImmutableList() {
    return Collector.of(ArrayList::new, List::add,
    (left, right) -> {
      left.addAll(right);
      return left;
    }, Collections::unmodifiableList);
}

カスタムCollectorsの実装の詳細については、this articleのセクション4を参照してください。 以上です。 上記のメソッドはカスタムクラスの一部です

これで、他の組み込みCollectorsと同じように使用できます。

@Test
public void whenCollectToMyImmutableListCollector_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c", "d");
    List result = givenList.stream()
      .collect(MyImmutableListCollector.toImmutableList());
}

最後に、出力を確認しましょう。

class java.util.Collections$UnmodifiableRandomAccessList