Параллельные стримы
Ленивость (lazy evaluation) — ключевое для понимания стримов. Промежуточные операции ничего не выполняют, пока не вызвана терминальная. И когда она вызвана, элементы идут по конвейеру по одному целиком, а не «весь filter, потом весь map».
Из ленивости следует:
- Короткое замыкание (short-circuit).
findFirst,anyMatch,limitмогут остановить конвейер, как только результат ясен — не обходя всю коллекцию. - Одноразовость. После терминальной операции стрим использовать нельзя — нужен новый.
Параллельные стримы. collection.parallelStream() разбивает работу на потоки через общий ForkJoinPool:
list.parallelStream().filter(...).collect(...);
Выгодно только на больших объёмах и независимых операциях. Опасности: накладные расходы на разбиение (на малых данных медленнее обычного), и гонки данных, если лямбды меняют общее состояние. Внутри стрима — никаких побочных эффектов на внешние переменные.
Stateless vs stateful. map, filter не зависят от других элементов (stateless) — легко параллелятся. sorted, distinct (stateful) требуют видеть все элементы и дороже в параллели.
• когда параллельные стримы выгодны, а когда опасны.