Поведение метода Stream peek () - PullRequest
2 голосов
/ 07 апреля 2019
List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
long result = nums
        .stream()
        .peek(System.out::print)
        .map(n->n*n)
        .filter(n->n>20)
        .peek(System.out::print)
        .count();
System.out.println(result);     

Почему бы не печатать 12345625362 вместо 1234525362?

Ответы [ 2 ]

5 голосов
/ 07 апреля 2019

Если мы добавим пробелы в println в peek, мы сможем лучше понять, почему это происходит:

long result2 = nums.stream()
                   .peek(e -> System.out.print(e + " "))
                   .map(n->n*n)
                   .filter(n->n>20)
                   .peek(e -> System.out.print(e + " "))
                   .count();

Это выводит:

1 2 3 4 5 25 6 36 

Как видите, 1 проходит, распечатывается, не проходит фильтр и, следовательно, квадрат не печатается. То же самое верно для 2, 3 и 4. Затем 5 проходит и печатается. Он проходит фильтр, поэтому 25 печатается. Пока что имеем:

1 2 3 4 5 25

Затем шесть проходит аналогичным образом, и у нас остается

1 2 3 4 5 25 6 36 

А затем System.out.println(result); печатается. Поскольку последний вызов был print, а не println, он печатается в той же строке, поэтому добавляется 2. Если мы уберем пробелы, это даст:

12345256362

Какой результат

1 голос
/ 07 апреля 2019

Все потоковые операции сначала применяются к 1, сначала peek / print, затем map, а затем filter, удаляя элемент. То же самое происходит и с 2, 3 и 4. После этого получается 1 2 3 4.

Затем в течение 5 мы peek / print, затем map, filter оставляем элемент в такте и затем peek / print в квадрате. Выход 5 25

То же самое для 6. Вывод: 6 36.

Все вместе 1234 525 636 -> 1234525636

И затем окончательный 2 для count.

...