Jes*_*per 53 scala views scala-collections
在Scala中,对于许多(所有?)类型的集合,您可以创建视图.
究竟是什么视图以及视图有用的目的是什么?
Mor*_*itz 47
视图是集合的非严格版本.这意味着元素是在访问时计算的,而不是像普通集合中那样急切.
作为示例,请使用以下代码:
val xs = List.tabulate(5)(_ + 1)
val ys = xs.view map { x => println(x); x * x }
Run Code Online (Sandbox Code Playgroud)
只是这样不会打印任何内容,但每次访问列表都会执行计算并打印值,即每次调用ys.head都会导致1打印.如果你想再次获得该系列的严格版本,你可以打电话force给它.在这种情况下,您将看到打印出的所有数字.
视图的一个用途是当您需要遍历计算成本高昂的值集合时,您一次只需要一个值.此外,视图允许您通过调用toStream它们来构建延迟序列,这些序列也将缓存已评估的元素.
Mar*_*ell 14
一个用例是当你需要收集元素转换的第一个结果时:
case class Transform(n: Int) { println("Transform "+n)}
val list = List(1,2,3,4,5)
list.view.map(v => Transform(v)).collectFirst{case Transform(3) => println("found")}
Run Code Online (Sandbox Code Playgroud)
打印:
Transform 1
Transform 2
Transform 3
found
Run Code Online (Sandbox Code Playgroud)
而:
list.map(v => Transform(v)).collectFirst{case Transform(3) => println("found")}
Run Code Online (Sandbox Code Playgroud)
打印:
Transform 1
Transform 2
Transform 3
Transform 4
Transform 5
found
Run Code Online (Sandbox Code Playgroud)
默认情况下,Scala集合在其所有变换器中都是严格的,除了
Stream它之外,懒惰地实现了所有变换器方法.但是,有一种系统的方法可以将每个集合转换为惰性集合,反之亦然,这是基于集合视图.一个观点是一种特殊类型的集合,代表一些基本的集合,但懒洋洋地实现了所有变压器....
您可能想要考虑使用视图有两个原因.首先是表现.您已经看到,通过将集合切换到视图,可以避免构建中间结果.这些节省非常重要.
...
第二个用例适用于可变序列的视图.这些视图上的许多变换器函数提供了进入原始序列的窗口,然后可以使用该窗口选择性地更新该序列的一些元素.