Sie unterscheiden sich stark im potenziellen Speicherbedarf zur Laufzeit. Während Sie alle Daten collect()
sammeln und in die Sammlung aufnehmen, werden Sie ausdrücklich aufgefordert, anzugeben, wie die Daten reduziert werden sollen, die den Stream durchlaufen haben.reduce()
Wenn Sie beispielsweise einige Daten aus einer Datei lesen, verarbeiten und in eine Datenbank einfügen möchten, erhalten Sie möglicherweise einen ähnlichen Java-Stream-Code:
streamDataFromFile(file)
.map(data -> processData(data))
.map(result -> database.save(result))
.collect(Collectors.toList());
In diesem Fall wird collect()
Java verwendet, um Daten zu streamen und das Ergebnis in der Datenbank zu speichern. Ohne collect()
die Daten wird nie gelesen und nie gespeichert.
Dieser Code generiert gerne einen java.lang.OutOfMemoryError: Java heap space
Laufzeitfehler, wenn die Dateigröße groß genug oder die Heap-Größe niedrig genug ist. Der offensichtliche Grund ist, dass versucht wird, alle Daten, die es durch den Stream geschafft haben (und tatsächlich bereits in der Datenbank gespeichert wurden), in die resultierende Sammlung zu stapeln, was den Heap in die Luft sprengt.
Wenn Sie jedoch ersetzen collect()
mit reduce()
- es wird kein Problem mehr sein , da letzteres reduziert und all verwirft die Daten , die sie durch gemacht.
Im vorgestellten Beispiel ersetzen Sie einfach collect()
etwas durch reduce
:
.reduce(0L, (aLong, result) -> aLong, (aLong1, aLong2) -> aLong1);
Sie müssen sich nicht einmal darum kümmern, dass die Berechnung von der abhängig ist, result
da Java keine reine FP-Sprache (Functional Programming) ist und die Daten, die am Ende des Streams nicht verwendet werden, aufgrund möglicher Nebenwirkungen nicht optimieren kann .