Shankar
Shankar

Reputation: 8967

Scala - Difference between Stream API Filter method vs List withFilter method

I have a Scala List[String], i converted the List to Stream using toStream method.

val list = List("shankar","ramesh","aarush","bujji")
val stream = list.toStream

Now what's the difference between these two, both are lazy evaluated.

println(list.toStream.filter { x => x.equals("bujji") })
println(list.withFilter { x => x.equals("bujji") })

Upvotes: 2

Views: 667

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170859

  1. One difference is their return type and so what you can do with result. You can pattern-match a Stream, take its headOption, mkString, etc.; the only methods of FilterMonadic are map, foreach, flatMap, and withFilter.

  2. If you assign the result of list.withFilter to a variable, and then use it (by calling one of FilterMonadic methods: map, foreach, or flatMap) multiple times, it will iterate over the entire list and check the predicate on each element every time; if you do the same with list.toStream.filter, it will only iterate over the original list once (and possibly not to the end, depending on what exactly you do).

  3. Stream#filter is less lazy: it needs to find the first satisfying element (if one exists) immediately.

To see 2 and 3 in action:

val listWithFilter = list.withFilter { x => println(s"Checking $x for listWithFilter"); x.equals("bujji") }
val filteredStream = stream.filter { x => println(s"Checking $x for filteredStream"); x.equals("bujji") }

listWithFilter.foreach { x => println(s"listWithFilter contains $x") }
listWithFilter.foreach { x => println(s"listWithFilter contains $x") }

filteredStream.foreach { x => println(s"filteredStream contains $x") }
filteredStream.foreach { x => println(s"filteredStream contains $x") }

produces

Checking shankar for filteredStream
Checking ramesh for filteredStream
Checking aarush for filteredStream
Checking bujji for filteredStream
Checking shankar for listWithFilter
Checking ramesh for listWithFilter
Checking aarush for listWithFilter
Checking bujji for listWithFilter
listWithFilter contains bujji
Checking shankar for listWithFilter
Checking ramesh for listWithFilter
Checking aarush for listWithFilter
Checking bujji for listWithFilter
listWithFilter contains bujji
filteredStream contains bujji
filteredStream contains bujji

Upvotes: 1

Related Questions