В Java при роботе с filter, map и т.д. нужно вызывать метод stream(). Зачем и почему так спроектировано?
В Java нет методов расширения, потому на коллекцию можно "навешивать" функциональность аналогичным образом (C#/LINQ), оборачивая коллекцию в Stream<T>.
stream - это рецепт потоковой обработки данных. чтобы он что-либо сделал, нужна терминальная операция. это сделано для ленивости.
например: 
listOf(1,2,3,4,5).stream().filter(it -> it  > 3).map(it -> it + 1)
такая строчка не сделает ничего, так как стрим не закрыт (нет терминальной операции)
listOf(1,2,3,4,5).stream().filter(it -> it  > 3).map(it -> it + 1).collect(toList())
теперь есть терминальная операция collect и строка отработает как ожидается.
причем выполнится все это лениво (в одном цикле), то есть мы не будем обходить list 2 раза, мы обойдем его 1 раз последовательно применяя операции
в данном случае элемент проверяется на >3, увеличивается на 1, следующее число проверяется на >3. увеличивается на 1 и тд