Java 8 Stream IllegalStateException: Stream wurde bereits bearbeitet oder geschlossen

8

Ich versuche, Order-Instanzen mithilfe der Stream-API zu generieren. Ich habe eine Factory-Funktion, die den Auftrag erstellt, und ein DoubleStream wird verwendet, um den Betrag der Bestellung zu initialisieren.

%Vor%

Wenn ich die Order-Instanz mit einem Literal (1.0) initialisiere, funktioniert das problemlos. Wenn ich den DoubleStream zum Erstellen eines zufälligen Betrags verwende, wird die Ausnahme ausgelöst.

Irgendeine Idee, wie Sie das beheben können?

TIA,

Ole

    
Ole 16.01.2015, 18:29
quelle

6 Antworten

13

Die Antwort ist im Javadoc von Stream (betont meins):

  

Ein Stream sollte nur einmal () aufgerufen werden (Aufruf einer Zwischen- oder Terminal-Stream-Operation). Dies schließt zum Beispiel "gegabelte" Ströme aus, wobei die gleiche Quelle zwei oder mehr Pipelines oder mehrere Traversierungen desselben Stroms speist. Eine Stream-Implementierung kann IllegalStateException auslösen, wenn sie feststellt, dass der Stream wiederverwendet wird .

Und in Ihrem Code verwenden Sie den Stream zweimal (einmal in createOrder() und die andere Verwendung bei .limit().forEach()

    
fge 16.01.2015, 18:36
quelle
4

Wie bereits in anderen Antworten erwähnt, sind Stream s Einwegartikel und Sie müssen jedes Mal, wenn Sie eins benötigen, ein neues Stream erstellen.

Aber schließlich ist das nicht kompliziert, wenn Sie alle Ihre Versuche entfernen, Zwischenergebnisse zu speichern. Ihr gesamter Code kann wie folgt ausgedrückt werden:

%Vor%

oder noch einfacher

%Vor%     
Holger 16.01.2015 19:59
quelle
1

Wie fge angibt , können Sie Stream nicht mehr als einmal konsumieren (sollten) / p>

  

Irgendeine Idee, wie Sie das beheben können?

Aus dem Javadoc von Random#doubles(double, double)

  

Ein Pseudozufallsdoppelwert wird erzeugt, als ob es das Ergebnis von ist   Aufruf der folgenden Methode mit dem Ursprung und der Grenze:

%Vor%

Implementieren Sie eine solche Methode und verwenden Sie sie, um jedes Mal einen neuen double -Wert zu erhalten, anstatt zu versuchen, sie von einem DoubleStream zu erhalten. Möglicherweise verwenden Sie DoubleSupplier .

%Vor%

Wenn Sie die Methode nextDouble nicht wiederverwenden, können Sie die Werte 50.0 und 200.0 inline einfügen.

    
Sotirios Delimanolis 16.01.2015 18:45
quelle
0

Danke - das war sehr hilfreich. Ich habe auch eine andere Implementierung gefunden, die jetzt gut funktioniert:

%Vor%

Nochmals vielen Dank!

Ole

    
Ole 16.01.2015 20:36
quelle
0

Ihre Methode könnte stattdessen ein Einstrich sein. Sie müssen mapToObj , nicht map

verwenden %Vor%     
user2336315 16.01.2015 21:55
quelle
0

Sie sollten die Supplier-Funktionsschnittstelle für Ihre Initialisierung wie folgt verwenden

%Vor%

Und ändere deinen Weg, um doppelt so zu werden

%Vor%

Dann funktioniert es normal.

Dieser Weg wurde aus dem Post Stream wurde bereits betrieben oder geschlossen Ausnahme

    
David Pham 20.11.2017 10:34
quelle