Shankar Shankar - 26 days ago 16
Scala Question

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

Answer
  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
Comments