Java Stream Verwendung des vorherigen Elements in Foreach Lambda

8

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

verwendet %Vor%

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?

    
Panciz 02.09.2016, 09:38
quelle

3 Antworten

0

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

auszuführen
  

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.

    
Sergey Rybalkin 02.09.2016, 10:03
quelle
5
  

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.

    
Journeycorner 02.09.2016 12:00
quelle
0

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.

%Vor%

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.

    
Renan Paul Blanco 20.11.2017 18:19
quelle

Tags und Links