Java 8 Lambda: Umwandlung der Sammlung in die Map des Elements, Iterationsposition

8

Wie konvertiert man eine Sammlung wie ["a", "b", "c"] in eine Karte wie {"a": 0, "b": 1, "c": 2} mit den Werten die Reihenfolge der Iteration. Gibt es einen JDK8 mit Stream und Sammler? Alte Modeweise ist so:

%Vor%     
danial 30.07.2014, 15:44
quelle

6 Antworten

6

Wenn Sie keinen parallelen Datenstrom benötigen, können Sie die Länge der Karte als Indexzähler verwenden:

%Vor%     
maba 30.07.2014 16:01
quelle
6

Hier ist ein Ansatz:

%Vor%

Nicht unbedingt ein Einzeiler oder kürzer als die einfache Schleife, aber es funktioniert mit einem parallelen Stream, wenn Sie toMap in toConcurrentMap ändern.

Beachten Sie auch, dass Sie davon ausgehen, dass Sie eine zufällige Zugriffsliste haben, nicht eine allgemeine Collection . Wenn Sie ein Collection haben, über das Sie sonst keine Annahmen treffen können, können Sie nicht viel anderes tun, als es nacheinander zu durchlaufen und einen Zähler zu erhöhen.

AKTUALISIEREN

Das OP hat klargestellt, dass die Eingabe ein Collection und nicht ein List ist, so dass das obige nicht zutrifft. Es scheint, dass wir sehr wenig von der Eingabe Collection annehmen können. Das OP hat eine Iterationsreihenfolge angegeben. Bei einem sequenziellen Iterator werden die Elemente in einige Reihenfolge ausgegeben, obwohl keine Garantie dafür gegeben werden kann. Es kann sich von Lauf zu Lauf oder sogar von einer Iteration zur nächsten ändern (obwohl dies in der Praxis ungewöhnlich wäre - es sei denn, die zugrunde liegende Sammlung wird geändert).

Wenn die genaue Iterationsreihenfolge beibehalten werden muss, glaube ich nicht, dass es eine Möglichkeit gibt, sie im Ergebnis Map zu erhalten, ohne die Eingabe Collection sequentiell zu durchlaufen.

Wenn jedoch die genaue Iterationsreihenfolge nicht wichtig ist und die Ausgabe Map für jedes Eingabeelement eindeutige Werte hat, dann ist es möglich, parallel dazu so etwas zu tun:

%Vor%

Dies ist jetzt weit von einem Einzeiler. Mir ist auch nicht klar, wie nützlich es ist. :-) Aber es zeigt, dass es möglich ist, so etwas parallel zu machen. Beachten Sie, dass wir den Zugriff auf den Iterator der Eingabesammlung synchronisieren mussten, da dieser aus mehreren Threads aufgerufen wird. Beachten Sie auch, dass dies eine ungewöhnliche Verwendung des Iterators ist, da wir nie hasNext aufrufen und wir annehmen, dass es sicher ist, next genau so oft aufzurufen wie vom size() der Eingabesammlung zurückgegeben.

    
Stuart Marks 30.07.2014 17:08
quelle
2

Basierend auf mabas Antwort lautet die allgemeine Lösung:

%Vor%

Aus der Dokumentation von void forEachOrdered(Consumer<? super T> action) :

  

Diese Operation verarbeitet die Elemente nacheinander, in der Reihenfolge der Begegnung, falls eine existiert.

Der wichtige Aspekt hier, dass er die Reihenfolge beibehält, wenn es einen gibt, z. Wenn die Collection eine SortedSet oder eine List ist. Ein solcher Stream wird als geordneter Stream bezeichnet (nicht um den sortierten Stream zu verwechseln). Es kann die Consumer-Methode durch verschiedene Threads aufrufen, aber immer die "eine nach der anderen" und Thread-Sicherheitsgarantie gewährleisten.

Natürlich wird es nicht von der parallelen Ausführung profitieren, wenn der Stream parallel ist.

Der Vollständigkeit halber ist hier die Lösung, die sogar bei parallelen Strömen funktioniert, die die parallele Verarbeitung verwenden, wenn sie immer noch geordnet sind:

%Vor%     
Holger 31.07.2014 15:23
quelle
1

Wenn es Ihnen nichts ausmacht, Bibliotheken von Drittanbietern zu verwenden, hat meine cyclops-reac -Bibliothek Erweiterungen für alle JDK Collection Typen, mit einer großen Anzahl von leistungsfähigen Funktionen, so dass Sie könnte dies wie folgt umsetzen: -

%Vor%

cyclops-react Sammlungs-Erweiterungen sind eifrig, damit Sie mit unserer Stream-Erweiterung eine bessere Leistung erzielen, ReactiveSeq (wodurch jOOλs Seq erweitert wird, was wiederum eine Erweiterung von JDKs java.util.stream.Stream ist, implementiert es auch die reaktiven Streams api).

%Vor%     
John McClean 24.02.2016 16:24
quelle
0

Versuchen Sie

%Vor%     
Syam S 30.07.2014 15:52
quelle
0

Sie können AtomicInteger als Index im Stream verwenden:     

%Vor%     
K. Gol 26.09.2016 13:58
quelle

Tags und Links