2017-01-20 7 views
13

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

"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 кажется мне более разумным, потому что потоки лениво оценены и Я не собирал и не пытался распечатать результат. Но в Scala, даже если я не потреблял поток, он печатает некоторую информацию. Итак, мой вопрос заключается в том, что вызывает эту разницу?

ответ

10

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

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

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

Если вы хотите полный лени, идти с withFilter:

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

Для более см withFilter instead of filter.