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

Scala Поток против разрыва лжи Java Stream

Я новичок в концепции ленивой оценки. Когда я выполняю эту строку кода в Scala;

"12334".grouped(1).toStream.filter{n => println("n:" +n ); n=="3";}

Он печатает:

n:1
n:2
n:3

Но когда я запускаю нечто похожее в Java, например:

List<String> myList = new ArrayList<>(Arrays.asList("12334".split("")));

Stream<String> myList2 = myList.stream().filter(a -> {System.out.println("a:" +a);return "3".equals(a);});

Он завершает работу без каких-либо изменений в консоли. Поведение Java кажется мне более разумным, потому что Streams лениво оценивается и Я не собирал и не пытался напечатать результат. Но в Scala, даже если я не потреблял поток, он распечатывает некоторую информацию. Итак, мой вопрос в том, что вызывает эту разницу?

4b9b3361

Ответ 1

Это связано с тем, что filter не совсем ленив. Он имеет этот кусок кода:

while (!rest.isEmpty && !p(rest.head)) rest = rest.tail

Что вызывает материализацию и фактическую фильтрацию Stream.

Если вам нужна полная лень, перейдите к withFilter:

"12334".grouped(1).toStream.withFilter { n => println("n:" +n ); n=="3"; }

Подробнее см. withFilter вместо фильтра.