Neue Stream Collectors in Java 9

Neue Stream Collectors in Java 9

1. Überblick

Collectors wurden in Java 8 hinzugefügt, wodurch Eingabeelemente in veränderlichen Containern wieMap,List undSet akkumuliert wurden.

In diesem Artikel werden wirtwo new collectors added in Java 9: Collectors.filtering andCollectors.flatMapping untersuchen, die in Kombination mitCollectors.groupingBy verwendet werden, um intelligente Sammlungen von Elementen bereitzustellen.

2. Filtering Collector

DasCollectors.filtering ist ähnlich demStream filter(); Es wird für die Eingabeelemente vonfilteringverwendet, jedoch für verschiedene Szenarien. DasStream’sfilter wird in der Stromkette verwendet, während dasfiltering einCollector ist, das zusammen mitgroupingBy verwendet werden soll.

MitStream’sfilter werden die Werte zuerst gefiltert und dann gruppiert. Auf diese Weise gehen die herausgefilterten Werte verloren und es gibt keine Spur davon. Wenn wir eine Ablaufverfolgung benötigen, müssen wir zuerst gruppieren und dann eine Filterung anwenden, die tatsächlich dieCollectors.filtering ausführt.

Collectors.filtering übernimmt eine Funktion zum Filtern der Eingabeelemente und einen Kollektor zum Sammeln der gefilterten Elemente:

@Test
public void givenList_whenSatifyPredicate_thenMapValueWithOccurences() {
    List numbers = List.of(1, 2, 3, 5, 5);

    Map result = numbers.stream()
      .filter(val -> val > 3)
      .collect(Collectors.groupingBy(i -> i, Collectors.counting()));

    assertEquals(1, result.size());

    result = numbers.stream()
      .collect(Collectors.groupingBy(i -> i,
        Collectors.filtering(val -> val > 3, Collectors.counting())));

    assertEquals(4, result.size());
}

3. FlatMapping Collector

Collectors.flatMapping ähneltCollectors.mapping, hat jedoch ein feinkörnigeres Ziel. Sowohl die Kollektoren übernehmen eine Funktion als auch einen Kollektor, in dem die Elemente gesammelt werden, aber die Funktion vonflatMappingakzeptiertStream von Elementen, die dann vom Kollektor akkumuliert werden.

Sehen wir uns die folgende Modellklasse an:

class Blog {
    private String authorName;
    private List comments;

    // constructor and getters
}

MitCollectors.flatMapping können wir die Zwischensammlung überspringen und direkt in einen einzelnen Container schreiben, der der durchCollectors.groupingBy definierten Gruppe zugeordnet ist:

@Test
public void givenListOfBlogs_whenAuthorName_thenMapAuthorWithComments() {
    Blog blog1 = new Blog("1", "Nice", "Very Nice");
    Blog blog2 = new Blog("2", "Disappointing", "Ok", "Could be better");
    List blogs = List.of(blog1, blog2);

    Map>> authorComments1 = blogs.stream()
     .collect(Collectors.groupingBy(Blog::getAuthorName,
       Collectors.mapping(Blog::getComments, Collectors.toList())));

    assertEquals(2, authorComments1.size());
    assertEquals(2, authorComments1.get("1").get(0).size());
    assertEquals(3, authorComments1.get("2").get(0).size());

    Map> authorComments2 = blogs.stream()
      .collect(Collectors.groupingBy(Blog::getAuthorName,
        Collectors.flatMapping(blog -> blog.getComments().stream(),
        Collectors.toList())));

    assertEquals(2, authorComments2.size());
    assertEquals(2, authorComments2.get("1").size());
    assertEquals(3, authorComments2.get("2").size());
}

DasCollectors.mapping ordnet alle Kommentare des gruppierten Autors dem Container des Sammlers zu, d. H. List, während diese Zwischensammlung mitflatMapping entfernt wird, da sie einen direkten Stream der Kommentarliste liefert, die dem Collector-Container zugeordnet werden soll.

4. Fazit

Dieser Artikel veranschaulicht die Verwendung der neuenCollectors, die inJava9 eingeführt wurden, d.h. Collectors.filtering() and Collectors.flatMapping() used in combination with Collectors.groupingBy().

Diese Kollektoren können auch zusammen mitCollectors.partitioningBy() verwendet werden, es werden jedoch nur zwei Partitionen basierend auf den Bedingungen erstellt, und die tatsächliche Leistung der Kollektoren wird nicht genutzt. daher aus diesem Tutorial weggelassen.

Der vollständige Quellcode für die Codefragmente in diesem Lernprogramm istover on GitHub verfügbar.