14

I'm new to the concept of lazy evaluation. When I execute this line of code in Scala;

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

It prints out:

n:1
n:2
n:3

But when I run something similar in Java, like:

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);});

It terminates silently without writing anything to console line. Java's behavior seems more reasonable to me because Streams are lazily evaluated and I did not collect or try to print result. But in Scala even if I did not consume stream it prints out some information. So my question is what is causing that difference?

altayseyhan
  • 735
  • 1
  • 7
  • 18

1 Answers1

13

It's due to the fact that filter isn't entirely lazy. It has this piece of code:

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

Which causes materialization and actual filtering of the Stream.

If you want full laziness, go with withFilter:

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

For more see withFilter instead of filter.

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321