什么是集合的视图以及您何时想要使用它们?

时间:2010-07-29 10:23:15

标签: scala views scala-collections

在Scala中,对于许多(所有?)类型的集合,您可以创建视图。

视图究竟是什么,视图有哪些用途?

4 个答案:

答案 0 :(得分:47)

视图是集合的非严格版本。这意味着元素是在访问时计算的,而不是像普通集合中那样急切。

作为示例,请使用以下代码:

val xs = List.tabulate(5)(_ + 1)
val ys = xs.view map { x => println(x); x * x }

这不会打印任何内容,但每次访问列表都会执行计算并打印值,即每次调用ys.head都会导致打印1。如果您想再次获得该集合的严格版本,可以在其上调用force。在这种情况下,您将看到打印出的所有数字。

视图的一个用途是当您需要遍历计算成本高昂的值集合时,您一次只需要一个值。此外,您还可以通过调用toStream来构建延迟序列,这些序列也会缓存已评估的元素。

答案 1 :(得分:12)

一个用例是当你需要收集元素转换的第一个结果时:

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

打印:

Transform 1
Transform 2
Transform 3
found

while:

    list.map(v => Transform(v)).collectFirst{case Transform(3) => println("found")}

打印:

Transform 1
Transform 2
Transform 3
Transform 4
Transform 5
found

答案 2 :(得分:8)

请参阅Views中的Scala 2.8 Collections API

  

除了Stream之外,Scala集合默认在所有变换器中都是严格的,它们懒洋洋地实现了所有变换器方法。但是,有一种系统的方法可以将每个集合转换为惰性集合,而反之亦然,它基于集合视图。 视图是一种特殊的集合,代表一些基本集合,但是懒惰地实现所有变换器。

     

...

     

您可能想要考虑使用视图有两个原因。首先是表现。您已经看到,通过将集合切换到视图,可以避免构建中间结果。这些节省非常重要。

     

...

     

第二个用例适用于可变序列的视图。这些视图上的许多变换器函数提供了一个进入原始序列的窗口,然后可以用它来选择性地更新该序列的某些元素。

答案 3 :(得分:0)

视图用于延迟计算,但不用于保存内存。

当您针对集合创建视图时,已经为集合分配了内存。

使用val view = Range(1,9).view.创建视图时,已经为该集合分配了内存,如果它太大,例如Range(1,1000000000),则OOM无法避免