Ich habe eine Liste von Zahlen mit einigen 0s
drin. Da 0
ein ungültiges Maß in meiner Situation bedeutet, muss ich das Element 0
valued mit dem ersten Element non 0 ändern, das ich an den vorherigen Positionen finden kann.
Zum Beispiel die Liste
%Vor%muss
werden %Vor% Dies ist die Implementierung, die das klassische for each
Gibt es eine Möglichkeit, dies mit den Java-Streams und Lambda-Funktionen zu implementieren?
Da ich weiß, dass ich die Quelle des Streams im foreach Lambda nicht ändern darf, ist die Liste eigentlich eine Liste von Objekten und ich ändere nicht das Element der Liste, sondern ich weise einfach neue Werte zu.
Dies war meine erste Lösung
%Vor%Aber ich lese auch hier
Es ist am besten, wenn die lambdas an Stream-Operationen übergeben werden Effekt frei. das heißt, dass sie keinen Heap - basierten Zustand mutieren oder Führen Sie während der Ausführung alle E / A aus.
Das ist was mich beunruhigt
Die Daten sind partitioniert, es gibt keine Garantie dafür, dass ein bestimmtes Element vorhanden ist verarbeitet, wurden alle Elemente, die diesem Element vorangingen, bereits verarbeitet.
Kann diese Lösung zu ungültigen Ergebnissen führen, wenn die Anzahl der Elemente in der Liste hoch ist? ?
Event, wenn ich parallelStream()
nicht verwende?
Sie können den Status von Objekten im Stream ändern. Sie können den Status der Datenquelle jedoch nicht ändern.
Das Problem ist das gleiche wie beim klassischen Iterieren.
Verwenden Sie forEachOrdered()
, um
Eine Aktion für jedes Element dieses Streams in der Reihenfolge der Begegnungen des Streams, wenn der Stream eine definierte Begegnungsreihenfolge aufweist
Wenn Sie
anrufen %Vor%Alle Elemente werden nacheinander in der Reihenfolge verarbeitet.
Bei sequentiellen Streams scheint forEach
die Reihenfolge zu respektieren.
Es ist am besten, wenn die lambdas an Stream-Operationen übergeben werden Effekt frei. das heißt, dass sie keinen Heap - basierten Zustand mutieren oder Führen Sie während der Ausführung alle E / A aus.
Ihre Lösung hat tatsächlich einen Nebeneffekt , sie ändert Ihre Quellenliste in eine Ressourcenliste. Um dies zu vermeiden, benötigen Sie den Kartenoperator und transformieren Ihren Stream in eine Sammlung. Da Sie nicht auf das vorherige Element zugreifen können, muss der Status außerhalb in einem letzten Feld gespeichert werden. Aus Gründen der Kürze habe ich Integer anstelle Ihres Objekts verwendet:
%Vor%Die Verwendung eines Streams für Ihr Problem ist nicht die beste Lösung, es sei denn, Sie benötigen einige zusätzliche Operationen wie Filter, andere Map-Operationen oder Sortieren.
Als Erstes solltest du den Status innerhalb eines Lambda nicht mutieren. Das heißt, Sie könnten eine benutzerdefinierte Liste verwenden, die ArrayList
erweitert und die Methoden iterator()
und spliterator()
überschreibt.
Beachten Sie, dass hier eine Klasse Pair
verwendet wird, die ich hier der Kürze wegen weggelassen habe.
Ich würde es dann so benutzen.
%Vor%Beachten Sie, dass dies nicht mit einem parallelen Stream getestet wird. Tatsächlich bin ich mir fast sicher, dass es nicht parallel funktionieren würde.