根据斯卡拉多克的说法,
视图是某些集合的惰性版本。映射或过滤器或++等集合转换器在应用于视图时不会遍历任何元素。相反,他们创建了一个新视图,它只记录需要应用操作的事实。
这意味着在访问元素之前不会应用操作。但是平行怎么样?
看一下这个例子:
def tn = Thread.currentThread.getName
val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace")
val pvs = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase}
第二个将打印出如下:
当您在foreach
上应用pvs
时,会输出:
我无法理解为什么 Parallel 风格的表现与普通风格不同:
val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") // or read from a text file , e.g. article.txt
strList.view.filter{s => println("f"); s == "I"}.map{s => println("m"); s.toLowerCase}.foreach(s => println("p"))
答案 0 :(得分:1)
因为如果表达式是并行集合视图,解释器通过强制它来计算表达式,以便它可以打印它(实质上强制视图)。尝试将其作为独立的Scala程序运行,或者执行此操作:
scala> object foo { var bar: AnyRef = null }
scala> foo.bar = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase}
编辑:
上面的另一个问题是并行视图上的filter
方法 - 与常规视图不同,它是通过强制集合来实现的。这意味着当您在并行filter
上调用view
时,整个过滤后的集合将被强制进入数组,并且必须调用与过滤器关联的谓词。像groupBy
这样的方法在常规视图上执行相同的操作。