Ich habe eine Liste mit Typen List<A>
und mit der Kartenoperation eine kollektive Liste mit Typen List<B>
für alle A-Elemente, die in einer Liste zusammengeführt sind.
List<A> listofA = [A1, A2, A3, A4, A5, ...]
List<B> listofB = listofA.stream()
.map(a -> repo.getListofB(a))
.flatMap(Collection::stream)
.collect(Collectors.toList());
ohne flatmap
List<List<B>> listOflistofB = listofA.stream()
.map(a -> repo.getListofB(a))
.collect(Collectors.toList());
Ich möchte die Ergebnisse als Karte vom Typ sammeln Map<A, List<B>>
und bisher mit verschiedenen Collectors.toMap
oder Collectors.groupingBy
Optionen versuchen , aber nicht in der Lage sein, das gewünschte Ergebnis zu erzielen.
java
lambda
java-8
java-stream
collectors
Amitoj
quelle
quelle
A
Elemente in Ihrem wiederholtList<A>
?Antworten:
Sie können den
toMap
Kollektor mit einer begrenzten Methodenreferenz verwenden, um das zu erhalten, was Sie benötigen. Beachten Sie auch, dass diese Lösung davon ausgeht, dass Sie keine A-Instanzen in Ihrem Quellcontainer wiederholt haben. Wenn diese Voraussetzung erfüllt ist, erhalten Sie mit dieser Lösung das gewünschte Ergebnis. So sieht es aus.Wenn Sie doppelte A-Elemente haben, müssen Sie diese Zusammenführungsfunktion zusätzlich zu den oben angegebenen verwenden. Die Zusammenführungsfunktion behandelt etwaige Schlüsselkonflikte.
Und hier ist ein viel prägnanterer Java9-Ansatz, bei dem der
flatMapping
Kollektor verwendet wird, um wiederholte A-Elemente zu verarbeiten.quelle
Es wäre einfach,
quelle
Um zu erfassen,
Map
wo Schlüssel dieA
Objekte unverändert sind und die Werte die Liste der entsprechendenB
Objekte sind, können Sie dentoList()
Kollektor durch den folgenden Kollektor ersetzen :Das erste Argument definiert, wie der Schlüssel aus dem ursprünglichen Objekt berechnet wird :
identity()
Nimmt das ursprüngliche Objekt des Streams unverändert.Das zweite Argument definiert, wie der Wert berechnet wird. Hier besteht es also nur aus einem Aufruf Ihrer Methode, der a
A
in eine Liste von umwandeltB
.Da die
repo
Methode nur einen Parameter verwendet, können Sie die Übersichtlichkeit verbessern, indem Sie das Lambda durch eine Methodenreferenz ersetzen:quelle
In dieser Antwort zeige ich, was passiert, wenn Sie
A
Elemente in IhrerList<A> listofA
Liste wiederholt haben .Wenn Duplikate vorhanden
listofA
wären, würde der folgende Code einIllegalStateException
:Die Ausnahme wird möglicherweise ausgelöst, da
Collectors.toMap
nicht weiß, wie sie zusammengeführt werden soll Werte werden sollen, wenn eine Kollision in den Schlüsseln auftritt (dh wenn die Key Mapper-Funktion Duplikate zurückgibt, wie dies der Fall wäre,Function.identity()
wenn dielistofA
Liste wiederholte Elemente enthalten würde ).Dies ist in den Dokumenten klar angegeben :
Die Dokumente geben uns auch die Lösung: Wenn sich Elemente wiederholen, müssen wir eine Möglichkeit zum Zusammenführen von Werten bereitstellen. Hier ist eine solche Möglichkeit:
Dies verwendet die überladene Version
Collectors.toMap
, die eine Zusammenführungsfunktion als drittes Argument akzeptiert . Wird innerhalb der ZusammenführungsfunktionCollection.addAll
verwendet, um das hinzuzufügenB
A
Wird Elemente jedes wiederholten Elements für jedes Element in eine eindeutige Liste aufzunehmenA
.In der Value Mapper-Funktion wird eine neue
ArrayList
erstellt, damit das OriginalList<B>
von jederA
nicht mutiert wird. Während wir ein erstellenArraylist
, wissen wir im Voraus, dass es mutiert werden kann (dh wir können später Elemente hinzufügen, falls Duplikate vorhanden sindlistofA
).quelle