Scala - Stream API Filter 方法与 List withFilter 方法之间的区别

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

我有一个 Scala List[String],我使用 toStream 方法将列表转换为流。

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

现在这两个有什么区别,都是lazy评估的。

println(list.toStream.filter { x => x.equals("bujji") })
println(list.withFilter { x => x.equals("bujji") })
  1. 一个区别是它们的 return 类型以及您可以对结果做什么。您可以模式匹配 Stream,取其 headOptionmkString 等; FilterMonadic 的唯一方法是 mapforeachflatMapwithFilter.

  2. 如果将list.withFilter的结果赋给一个变量,然后使用它(通过调用FilterMonadic方法之一:mapforeach, or flatMap) 多次,它会遍历整个列表,每次检查每个元素上的谓词;如果你对 list.toStream.filter 做同样的事情,它只会迭代原始列表一次(并且可能不会结束,具体取决于你做什么)。

  3. Stream#filter 不那么懒惰:它需要立即找到第一个满足的元素(如果存在的话)。

要查看 2 和 3 的实际效果:

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

产生

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