Я бы хотел обработать список, отфильтровать его, а затем обработать весь отфильтрованный результат.
Обратите внимание, что поток также может быть бесконечным;)
Таким образом, получение бесконечного списка результатов не очень хорошая идея.
В основном потоки ленивы, и применение промежуточных операций к потоку без терминальной операции ничего не делает:
Например, следующий код ничего не печатает:
Stream<String> stream = Stream.of("hello","how","are", "you").filter(this::startsWithH)
private boolean startsWithH(String elem) {
System.out.println("Filtering element " + elem);
return elem.startsWith("h");
}
Теперь, когда вы применяете терминальную операцию, она все равно будет работать поэлементно:
Пример выполнения:
Stream<String> stream = Stream.of("hello","how","are", "you")
.filter(this::startsWithH)
.map(String::toUpperCase)
stream.collect(toList());
В этом примере выдается следующая цепочка выполнения:
- filter ("hello")
- map ("hello")
- filter ("how" )
- map ("как")
- filter ("are") <--- отфильтровано, вызов карты не будет выполнен </li>
- filter ("you" ) <--- отфильтровано, вызов map не будет выполняться </li>
Но если это так, вы не сможете по-настоящему работать с "целым" потоком в примере в этом вопросе (хорошо, есть операции с состоянием, которые должны работать со всем потоком, например sort , но это совсем другая история).
Другими словами, если вы хотите получить данные как сбор, вы должны, ну, собирать данные. Это больше не будет потоком.
Для этого вы должны использовать .collect()
. И если у вас есть бесконечный поток, не забудьте позвонить limit
beforehands;)