Neu in Java 12: The Teeing Collector

In diesem Artikel werden wir uns einen neuen Kollektor ansehen, der in Java 12 eingeführt wurde. Diese neue Funktion wurde im offiziellen JEP nicht angekündigt, da es sich um eine geringfügige Änderungsanforderung mit der Überschrift " Kollektor erstellen, der die Ergebnisse zweier anderer Kollektoren zusammenführt " handelte. Es wurde entwickelt, um Ergebnisse von zwei Sammlern zu kombinieren.


Alles interessant - unter dem Schnitt


Wenn Sie immer noch nicht wissen, was Sammler sind
Kollektoren sind spezielle Klassen, mit denen ein Stream in eine andere Datenstruktur konvertiert wird. Zum Beispiel in der list :
 list = Stream.of(1,2,3).collect(Collectors.toList()); //     1, 2  3 

Dies ist ein nutzloses Beispiel, da ein neuer Stream erstellt und sofort transformiert wird. Es soll die Verwendung von Sammlern zeigen

Die Dokumentation


Klicken Sie hier , um Collectors#teeing anzuzeigen. Laut offizieller Dokumentation:
„... gibt einen Sammler zurück, der aus zwei untergeordneten Sammlern besteht. Jedes Element, das an den resultierenden Kollektor übertragen wird, wird von beiden untergeordneten Kollektoren verarbeitet, und dann werden ihre Ergebnisse mithilfe einer speziellen Funktion kombiniert, die sie mit dem Endergebnis verbindet. “
Das Original
"... gibt einen Kollektor zurück, der aus zwei nachgeschalteten Kollektoren besteht. Jedes an den resultierenden Kollektor übergebene Element wird von beiden nachgeschalteten Kollektoren verarbeitet, und ihre Ergebnisse werden mithilfe der angegebenen Zusammenführungsfunktion zum Endergebnis zusammengeführt."
Methodenkopfzeile:

 static <T, R1, R2, R> Collector<T, ?, R> teeing( Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger) 

Interessante Tatsache


Dies ist ein Abschlag (Abschlag aus dem Englischen):



Teeing kam von einem Abschlag. Laut Wikipedia ist „ein T-Stück die häufigste Anpassung (Verbindungsteil einer Pipeline, ca. Übersetzer), die zum Kombinieren [oder Teilen] eines Flüssigkeitsstroms verwendet wird (in diesem Fall meinen wir Streams, Stream - Stream / Stream, Kommentarübersetzer).“
Andere Namen wurden vorgeschlagen: Halbieren (Teilen in 2 Teile), Duplexen, Bifurkieren (Teilen), Replikator, Fanout (Teilen), Tippen, Entpacken, Sammeln zu beiden und dann, BiCollecting, Erweitern (Erweitern), Gabeln usw.
Alle von Core-Entwicklern bewerteten Alternativen finden Sie hier .

Anwendungsbeispiele


Ich habe drei Beispiele für die Verwendung von Code mit unterschiedlichen Komplexitätsstufen zusammengestellt.

Gästeliste


Wir extrahieren zwei verschiedene Arten von Informationen aus der Liste der Objekte im Stream. Jeder Gast muss die Einladung annehmen und kann die Familie führen. Wir möchten wissen, wer die Reservierung bestätigt hat und wie viele Teilnehmer (einschließlich Gäste und Familienmitglieder) insgesamt anwesend sind .

 var result = Stream.of( // Guest(String name, boolean participating, Integer participantsNumber) new Guest("Marco", true, 3), new Guest("David", false, 2), new Guest("Roger",true, 6)) .collect(Collectors.teeing( //  ,    ,    Collectors.filtering(Guest::isParticipating, //        Collectors.mapping(o -> o.name, Collectors.toList())), //  ,       Collectors.summingInt(Guest::getParticipantsNumber), //      , //    EventParticipation::new )); System.out.println(result); //  // EventParticipation { guests = [Marco, Roger], // total number of participants = 11 } 


Gast
 class Guest { private String name; private boolean participating; private Integer participantsNumber; public Guest(String name, boolean participating, Integer participantsNumber) { this.name = name; this.participating = participating; this.participantsNumber = participantsNumber; } public boolean isParticipating() { return participating; } public Integer getParticipantsNumber() { return participantsNumber; } } 


Eventteilnahme
 class EventParticipation { private List<String> guestNameList; private Integer totalNumberOfParticipants; public EventParticipation(List<String> guestNameList, Integer totalNumberOfParticipants) { this.guestNameList = guestNameList; this.totalNumberOfParticipants = totalNumberOfParticipants; } @Override public String toString() { return "EventParticipation { " + "guests = " + guestNameList + ", total number of participants = " + totalNumberOfParticipants + " }"; }} 


Filtern Sie Namen in zwei verschiedenen Listen


In diesem Beispiel teilen wir den Namensstrom entsprechend dem Filter in zwei Listen auf.

 var result = Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One", "Angular Connect") .collect(Collectors.teeing( //   Collectors.filtering(n -> n.contains("xx"), Collectors.toList()), //   Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()), //  -       (List<String> list1, List<String> list2) -> List.of(list1, list2) )); System.out.println(result); // -> [[Devoxx, Voxxed Days], [Code One, Basel One]] 

Zähle und füge einen Strom von Zahlen hinzu


Möglicherweise haben Sie ein ähnliches Beispiel in Blogs gesehen, in denen Summe und Anzahl kombiniert werden, um den Durchschnitt zu ermitteln. Für dieses Beispiel ist kein Teeing erforderlich, und Sie können einfach AverageInt und einen einfachen Collector verwenden.

Im folgenden Beispiel werden Funktionen von Teeing , um zwei Werte zurückzugeben:

 var result = Stream.of(5, 12, 19, 21) .collect(Collectors.teeing( //   Collectors.counting(), //   Collectors.summingInt(n -> Integer.valueOf(n.toString())), // : (count, sum) -> new Result(count, sum); Result::new )); System.out.println(result); // -> {count=4, sum=57} 

Ergebnis
 class Result { private Long count; private Integer sum; public Result(Long count, Integer sum) { this.count = count; this.sum = sum; } @Override public String toString() { return "{" + "count=" + count + ", sum=" + sum + '}'; }} 


Mögliche Falle


Map.Entry

Viele Beispiele verwenden Map.Entry , um das Ergebnis einer BiFunction zu speichern. Bitte tun Sie dies nicht, da Sie das letzte Argument nicht in Map speichern können. In Java Core gibt es kein Standardobjekt zum Speichern von zwei Werten - Sie müssen es selbst erstellen.

Alles über neue Java 12-Funktionen


Weitere Informationen und interessante Fakten zu Java 12 finden Sie in dieser Präsentation .

Erfolgreiche Sammlerstücke!

Source: https://habr.com/ru/post/de445622/


All Articles