[JAVA] Detailliertes Verhalten der Stream API Stateful-Zwischenoperation und der Kurzschlussbeendigungsoperation

Detailliertes Verhalten der Stream API Stateful-Zwischenoperation und der Beendigungsoperation

Erstens ist das Problem.

Was ist mit der Konsolenausgabe des folgenden Codes?


//Frage 1
		Stream.of(1, 2, 3, 4, 5).map(i -> {
			System.out.println(i);
			return i * 2;
		}).filter(i -> i > 3).findFirst();
//Frage 2
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).findFirst();
//Frage 3
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).sorted().findFirst();
//Frage 4
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).distinct().findFirst();

Antworten

//Frage 1
1
2
//Frage 2
1
2
//Frage 3
1
2
3
4
5
//Frage 4
1
2

Kommentar

Frage 1

Die Stream-Verarbeitung von Java ist in "Generierung", "Zwischenoperation" und "Beendigungsoperation" unterteilt. Grundsätzlich der Teil, in dem die Generierung den Stream erstellt, die Methode, in der die Beendigungsoperation schließlich das Ergebnis zurückgibt, Es ist in Ordnung, wenn Sie sich die Zwischenoperation als den Teil vorstellen, der Stream von anderen Streams zurückgibt.

Die eigentliche Verarbeitung wird ausgeführt, wenn die Beendigungsoperation ausgeführt wird. Und im Grunde führt es die Beendigungsoperation für jedes Element aus, das in Stream fließt. Nicht alle Elemente werden zugeordnet und dann gefiltert. (Das Verhalten unterscheidet sich beispielsweise vom Schreiben von ähnlichem Code in ein Javascript-Array.)

Und FindFirst, das dieses Mal als Abschlussoperation übernommen wird, wird als Kurzschluss-Abschlussoperation unter den Abschlussoperationen bezeichnet. Eine Operation mit einem "Kurzschluss" endet, noch bevor alle im Strom fließenden Elemente ausgewertet werden, wenn die Bedingungen erfüllt sind. (Wenn die Kurzschlussoperation die Bedingungen erfüllt, ist es möglich, den Prozess zu beenden, ohne in eine Endlosschleife zu geraten, selbst für einen Stream, der einen Endloswert zurückgibt (z. B. einen Stream, der aus einem Iterator erstellt wurde, dessen Next immer true zurückgibt).)

In einer for- oder while-Schleife gibt es viele Prozesse, die unterbrochen werden, wenn auch nur eine Bedingung erfüllt ist, und den Rest ignorieren, dies geschieht jedoch automatisch. Es ist klug.

In diesem Fall kann findFirst den Wert zurückgeben, wenn 2 fließt, sodass die Stream-Verarbeitung bis zu 1 und 2 unterbrochen wird.

Frage 2

Es ist im Grunde das gleiche wie Frage 1. Wenn Sie unmittelbar nach dem Erstellen eines Streams mit 5 fließenden Elementen einen Blick darauf werfen, wird dieser anscheinend fünfmal ausgeführt. Die Stream-Verarbeitung stoppt bei 2, da das Ende die Kurzschlussabschlussverarbeitung ist.

Frage 3

In einigen Fällen werden die Elemente, die durch alle Streams fließen, ausgewertet, selbst wenn ein Kurzschlussabschluss durchgeführt wird. Dies ist der Fall bei "Stateful Intermediate Processing" dazwischen. In diesem Fall ist sortiert ein zustandsbehafteter Zwischenprozess. Da es sich um einen Prozess des Sortierens und Erhaltens desjenigen handelt, der zuerst die Bedingungen erfüllt, Natürlich ist es notwendig, alle Elemente logisch zu referenzieren.

Übrigens wird in Official Reference beschrieben, ob jeder Zwischenprozess zustandsbehaftet ist oder nicht. ..

Frage 4

Übrigens ist es nicht immer notwendig, auf alle Elemente mit einer zustandsbehafteten Zwischenoperation zu verweisen. unterscheiden ist auch eine zustandsbehaftete Zwischenoperation, die jedoch auch in 1 und 2 abgeschlossen ist. Tatsächlich werden alle Elemente in einem normal geordneten Stream immer nur referenziert, wenn sortiert verwendet wird.

Zusammenfassung

Beiseite

Bei ParallelStream ist das Verhalten etwas anders. Es wird lange dauern, also hier.

Recommended Posts

Detailliertes Verhalten der Stream API Stateful-Zwischenoperation und der Kurzschlussbeendigungsoperation
[Java] Stream API Zwischenoperation
[Java] Stream API - Stream-Beendigungsverarbeitung
[Java] Stream API - Stream Zwischenverarbeitung