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 sindKollektoren 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());
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(
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(
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(
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!