Erfassen Sie einen Java-Stream in eine unveränderliche Sammlung

Sammeln Sie einen Java-Stream in eine unveränderliche Sammlung

1. Einführung

In diesem kurzen Artikel werden verschiedene Möglichkeiten zum Sammeln von JavaStreamsbis unveränderlichenCollections –untersucht, die einen speziellen Ansatz erfordern, da StandardCollectorsnur mit veränderlichen Datenstrukturen arbeiten.

2. Maven-Abhängigkeit

Wir werden die Guava-Bibliothek von Google verwenden, um einige unserer Beispiele voranzutreiben:


    com.google.guava
    guava
    22.0

Wir können die neueste Version dieser Abhängigkeit vonhere erhalten.

3. Verwenden voncollectingAndThen() von Java

DiecollectingAndThen()-Methode aus derCollectors-Klasse von Java akzeptiertCollector undfinisherFunction, die auf das vonCollector: zurückgegebene Ergebnis angewendet werden

@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());
}

Da wir die toCollection() Collector nicht direkt, verwenden können, müssen wir Elemente in einer temporären Liste sammeln und daraus eine unveränderliche Liste erstellen.

In diesem Beispiel konvertieren wir einStream in einList mit dem KollektortoList() und erstellen dann einImmutableList. DasImmutableList ist Teil der Guava-Bibliothek. Wenn wir die Ausgabe in der Konsole protokollieren, erhalten wir die Klasse des Basiswerts

Wenn wir die Ausgabe in der Konsole protokollieren, erhalten wir die Klasse der zugrunde liegenden Implementierung vonList:

class com.google.common.collect.RegularImmutableList

4. Verwenden von GuavasCollectors

Beginnend mit Guava 21 enthält jede unveränderliche Klasse ein zugehörigesCollector, das genauso einfach zu verwenden ist wie StandardCollectors:

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

Die resultierende Instanz istRegularImmutableList:

class com.google.common.collect.RegularImmutableList

5. Erstellen eines benutzerdefinierten Sammlers

Gehen wir jetzt noch einen Schritt weiter und implementieren unsere benutzerdefiniertenCollector. Um dieses Ziel zu erreichen, verwenden wir die statischeCollector.of()-Methode:

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

Weitere Informationen zum Implementieren von benutzerdefiniertenCollectors finden Sie in Abschnitt 4 vonthis article. Und das ist es. Die obige Methode ist Teil unserer benutzerdefinierten Klasse

Wir können es jetzt wie jedes andere integrierteCollectors verwenden:

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

Lassen Sie uns abschließend die Ausgabe überprüfen:

class java.util.Collections$UnmodifiableRandomAccessList