Подтвердить что ты не робот

Java 8 Streams peek api

Я попробовал следующий фрагмент кода Java 8 с peek.

List<String> list = Arrays.asList("Bender", "Fry", "Leela");
list.stream().peek(System.out::println);

Однако на консоли ничего не распечатано. Если я сделаю это вместо:

list.stream().peek(System.out::println).forEach(System.out::println);

Я вижу следующее, которое выводит как просмотр, так и вызов foreach.

Bender
Bender
Fry
Fry
Leela
Leela

Оба foreach и peek принимают (Consumer<? super T> action) Итак, почему вывод отличается?

4b9b3361

Ответ 1

Javadoc упоминает следующее:

Промежуточные операции возвращают новый поток. Они всегда ленивы; выполнение промежуточной операции, такой как filter(), фактически не выполняет никакой фильтрации, а вместо этого создает новый поток, который при обходе содержит элементы исходного потока, которые соответствуют данному предикату. Обход источника конвейера не начинается до тех пор, пока не будет выполнена операция терминала в конвейере.

peek промежуточная операция ничего не делает. При применении терминальной операции, например foreach, результаты распечатываются, как видно.

Ответ 2

В документации для peek указано

Возвращает поток, состоящий из элементов этого потока, дополнительно выполняющий предоставленное действие для каждого элемента, поскольку элементы расходуются из результирующего потока. Это промежуточная операция.

Поэтому вам нужно что-то сделать с результирующим потоком для System.out.println, чтобы что-то сделать.

Ответ 3

Из документа Stream для метода peek:

... дополнительно выполняет предоставленное действие для каждого элемента , поскольку элементы потребляются из результирующего потока.

Ответ 4

Потоки в Java-8 ленивы, кроме того, скажем, если в потоке одна за другой есть две цепные операции, то вторая операция начинается, как только первая заканчивает обработку единицы элемента данных (при условии, что существует терминал в потоке).

Вот почему вы можете видеть повторяющиеся строки имен, получающие вывод.