2016-06-25 5 views
-3

Was ist der Unterschied zwischen (*)forEach und ohne? Was ist die Ausgabe und warum? Ich weiß ohne forEach nichts wird gedruckt ... aber warum Peek benötigt wird?Java Stream, Unterschied zwischen mit und ohne forEach

Als ich für peek weiß, dass Sie für System.out.println etwas mit dem resultierenden Strom zu tun, etwas zu tun ... aber es ist nicht hier getan werden muss scheint, und es läuft immer noch ....

public class NaturalNumbers 
     implements Supplier<Integer> { 
private int i = 0; 
public Integer get() { return ++i; } 
} 

public static void main(String[] args) { 
Stream<Integer> s = 
       Stream.generate(new NaturalNumbers()); 

s.limit(5) 
    .peek(System.out::println) 
    .forEach(System.out::println);/// ׂ (*) 
{ 
+1

* Was ist die Ausgabe *: Warum führen Sie nicht den Code und sehen Sie selbst? Dann lese die Dokumentation und verstehe warum? Was erwarten Sie, wenn Sie forEach oder peek entfernen und was stattdessen passiert? –

+0

ji denke, Sie müssen zuerst über Nebenwirkungen von 'für jeden '(https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) – emotionlessbananas

Antwort

2

peek ist nur ein Weg zu Peek innerhalb des Streams, es ändert es nicht, aber die Funktion in peek erhalten alle Elemente, die im Stream sind.

forEach ist ein Terminal-Vorgang, der alle Daten im Stream verbraucht und void zurückgibt.

Das Ergebnis des obigen Codes wird jede Nummer zweimal gedruckt werden, wenn Sie peek entfernen, erhalten Sie die Zahlen nur einmal gedruckt.

Wenn Sie forEach entfernen Sie nicht‘eine Ausgabe erhalten, weil Strom die Aktionen bis zum Terminalbetrieb nicht ausgeführt wird (wie zum Beispiel forEach, count) angetroffen wird.

+0

überprüfen, wenn Sie entfernen Mit 'forEach' werden keine Zahlen gedruckt, da keine Endaktion Elemente aus dem Stream verbraucht. –

+0

@MarkRotteveel Richtig habe ich vergessen, meine Antwort aktualisiert –

2

Es gibt eine Vorstellung von Terminal- und Zwischenoperationen. Terminal-Operationen sind der letzte Schritt - sie bewirken, dass alle Zwischenoperationen verarbeitet werden. Peek ist keine Terminaloperation.

Stream.of("one", "two", "three", "four") 
      .filter(e -> e.length() > 3) 
      .peek(e -> System.out.println("Filtered value: " + e)) 
      .map(String::toUpperCase) 
      .peek(e -> System.out.println("Mapped value: " + e)) 
      .collect(Collectors.toList()); 

Und ja, ich würde Sie in javadocs der Methode Peek aussehen empfehlen: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

Auch lesen Sie dieses Dokument https://docs.oracle.com/javase/tutorial/collections/streams/

Wie kann man wissen, ob ein Verfahren ein Terminalbetrieb ist oder ein Zwischenprodukt? So einfach es auch sein mag - Zwischenoperationen geben immer die Stream-Klasse zurück, während Terminaloperationen verschiedene Objekte zurückgeben können - optionale Klassen, einige Sammlungen, Primitive und so weiter.