Heim >Java >javaLernprogramm >Warum ist „filter()' nach „flatMap()' in Java-Streams nicht immer faul?
Warum filter() nach flatMap() in Java-Streams nicht völlig faul ist
In Java-Streams gilt filter() als faul Die Ausführung erfolgt also nicht sofort, sondern erst am Verbrauchsort. Wenn jedoch filter() auf flatMap() folgt, weicht sein Verhalten von echter Faulheit ab.
Demonstration
Bedenken Sie den folgenden Code:
Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
In diesem Beispiel wird filter() auf einen Stream von Ganzzahlen angewendet. Die Ausgabe zeigt, dass die Filterfunktion nur für das erste Element aufgerufen wird, wie bei einer verzögerten Auswertung erwartet.
1 Result: 1
Allerdings im folgenden Code:
Stream.of(1, 2, 3) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
Der Filter( )-Funktion wird auf einen Stream angewendet, der durch Anwenden von zwei flatMap()-Operationen generiert wird. Obwohl das erste Element im abgeflachten Stream die Filterbedingung erfüllt, wird die Filterfunktion weiterhin für die verbleibenden Elemente aufgerufen.
-1 0 1 0 1 2 1 2 3 Result: -1
Erklärung
Die Der Grund für dieses Verhalten ist, dass flatMap() für jedes Element im ursprünglichen Stream einen neuen Stream erstellt. Während filter() eine verzögerte Operation bleibt, unterstützt die Reduzierungsoperation keine vorzeitige Beendigung. Sobald der Abflachungsprozess beginnt, kann er daher nicht unterbrochen werden, selbst wenn die Filterbedingung später im Stream erfüllt wird.
Auswirkungen
Dieses Verhalten kann zu unerwarteten Ereignissen führen Konsequenzen, insbesondere beim Umgang mit unendlichen Strömen. Wenn beispielsweise der Eingabestrom für die flatMap()-Operation unendlich ist, versucht die filter()-Operation auf unbestimmte Zeit, ihre Funktion anzuwenden, auch wenn garantiert ist, dass sie nie ein passendes Element findet.
JDK-Korrekturen
Das hier beschriebene Problem wurde in Java 10 behoben (und auf Java 8 zurückportiert). In diesen Versionen wurde flatMap() optimiert, um eine vorzeitige Beendigung zu unterstützen, um sicherzustellen, dass das Verhalten von filter() und anderen Lazy-Operationen konsistent bleibt, unabhängig davon, ob sie flatMap() folgen.
Das obige ist der detaillierte Inhalt vonWarum ist „filter()' nach „flatMap()' in Java-Streams nicht immer faul?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!