Он будет перемещаться по всему потоку, представляя задачи для объединения пулов, разбивая список на части и передавая все элементы списка этой пустой лямбда. В настоящее время невозможно проверить во время выполнения, является ли выражение лямбда пустым или нет, поэтому его невозможно оптимизировать.
Аналогичная проблема возникает при использовании Collector
. Все коллекторы имеют операцию finisher
, но во многих случаях это функция идентификации, такая как x -> x
. В этом случае иногда код, который использует коллекторы, может быть сильно оптимизирован, но вы не можете точно определить, является ли предоставленная лямбда личность или нет. Для этого вместо этого была введена дополнительная характеристика коллектора под названием IDENTITY_FINISH
. Если бы можно было надежно определить, является ли предоставленная лямбда функцией идентификации, эта характеристика не нужна.
Также смотрите JDK-8067971 обсуждение. Это предполагает создание статических констант, таких как Predicate.TRUE
(всегда верно) или Predicate.FALSE
(всегда false) для оптимизации таких операций, как Stream.filter
. Например, если подано Predicate.TRUE
, тогда можно удалить этап фильтрации, и если будет предоставлен Predicate.FALSE
, тогда поток может быть заменен пустым потоком в этой точке. Опять же, можно было обнаружить во время выполнения, что поставленный предикат всегда прав, тогда было бы необязательно создавать такие константы.
Проверьте сгенерированный байт-код, но я ожидаю увидеть оптимизацию здесь. –
ForEach - это терминал op, который инициирует оценку потока. Элементы будут сгенерированы и переданы в лямбду do-nothing. –