Что произойдет, если я вызову limit () после filter () из Stream API? - PullRequest
1 голос
/ 12 марта 2019

Будут ли следующие элементы кода фильтровать, пока не будут найдены 3 элемента, которые проходят метод фильтрации, или отфильтровать все элементы?

manyItems.stream()
    .filter(it -> it.getValue > 100)
    .limit(3)
    ...

Ответы [ 2 ]

2 голосов
/ 12 марта 2019

filter() имеет ленивое исполнение.Это означает, что на самом деле он ничего не делает правильно, когда вы его называете.Вместо этого он просто возвращает новый Stream, который будет содержать элементы, которые соответствуют данному Predicate при прохождении.

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

Мы можем проверить это, вызвав peek():

Arrays.stream(new int[] {1, 2, 2, 2, 2})
      .filter(e->  e > 1)
      .peek(System.out::println)
      .limit(3)
      .average();      

(где average() может быть любой терминальной операцией, которая сама не замыкается на короткое замыкание)

Какие выходы:

2
2
2

(Обратите внимание, чтопоследние два не появляются после звонка на filter())

0 голосов
/ 12 марта 2019

Этот метод сначала применяет фильтр, а затем вызывает предел для фильтруемого потока.Вы можете легко попробовать это написать тест.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...