Java 8-Streams - Jeder Schritt in der Kette wird für die gesamte Eingabe ausgewertet oder werden Elemente durchlaufen?

8

Sagen Sie, wenn ich dieses triviale Programm habe

%Vor%

Hinter den Kulissen funktioniert es wie a) oder b)

A

%Vor%

B

%Vor%     
djhworld 29.03.2014, 19:56
quelle

2 Antworten

8

Es funktioniert wie Option B, nicht unbedingt in genau dieser Reihenfolge, sondern mehr dazu, dass es jede Operation für ein Element gleichzeitig ausführt.

Der Grund dafür ist, dass Variablen den Stream nur einmal übergeben , also müssen Sie alle Aktionen ausführen, wenn Sie dieses Element gerade haben, denn sobald das Element übergeben wurde, ist es für immer verschwunden ( aus der Sicht des Streams).

Ihr Code ist in einer linearen Einstellung sehr sehr sehr sehr ähnlich dem folgenden Code, dies ist eine sehr vereinfachte Version, aber ich hoffe, Sie bekommen die Idee:

%Vor%

Was Sie hier sehen, ist:

  • Als Eingabe eine Collection<String> , Ihre Eingabe.
  • A Function<String, String> entspricht Ihrem map() .
  • A Predciate<String> entspricht Ihrem filter() .
  • A Collector<String, ?, List<String>> entspricht Ihrem collect() , dies ist ein Kollektor, der auf Elemente vom Typ String operiert, Zwischenspeicher ? verwendet und ein List<String> .
  • angibt

Was es dann macht ist:

  • Besorgen Sie sich eine neue Liste vom Lieferanten (Typ: Supplier<List<String>> ) des Kollektors.
  • Schleife über jedes Element der Eingabe, intern gemacht, wenn in Stream<String> gearbeitet wird, ich benutze hier ein Collection<String> für die Explizität, so dass wir immer noch eine Verbindung zur alten Java 7 Welt haben.
  • Wenden Sie Ihre Zuordnungsfunktion an.
  • Testen Sie Ihr Filterprädikat.
  • Besorgen Sie sich den Akkumulator (Typ: BiConsumer<List<String>, String> ) des Kollektors toList , dies ist der binäre Konsument, der als Argumente den List<String> , den er bereits hat, und den String , den er hinzufügen möchte, verwendet.
  • Füttern Sie unsere list und in mit dem Akkumulator.

Bitte nehmen Sie sehr genau zur Kenntnis, dass die realen Implementierungen sehr viel fortgeschrittener sind, da Operationen in beliebiger Reihenfolge passieren können und mehrere passieren können, und vieles mehr.

    
skiwi 29.03.2014, 20:01
quelle
5

Einer der Vorteile von Streams ist lazy-evaluation von Zwischenoperationen . Das heißt, wenn die Terminal-Operation collect() in diesem Fall ausgeführt wird, fragt sie nach einem Element aus der vorherigen Zwischenoperation - filter() , das wiederum das Element von map() erhält, das wiederum mit dem ersten Element arbeitet %Code%. Der gleiche Fluss wird für alle Elemente verfolgt. Also ja, die Ausführung ist eher wie Option B.

Da auch der von list.stream() zurückgegebene Kollektor geordnet ist, werden die Elemente garantiert in der Reihenfolge ausgeführt. In einigen Fällen kann die Bewertung außer Betrieb gehen, wenn Collectors.toList() characteristicis wird für einen Collector gesetzt.

    
Rohit Jain 29.03.2014 20:03
quelle

Tags und Links