Scala 集合的视图是什么?您希望何时使用它们?

Scala 集合的视图是什么?您希望何时使用它们?,scala,views,scala-collections,Scala,Views,Scala Collections,在Scala中,对于许多(所有?)类型的集合,您可以创建视图 视图究竟是什么?视图对哪些用途有用?视图是集合的非严格版本。这意味着元素是在访问时计算的,而不是像在正常集合中那样急切地计算的 以以下代码为例: val xs = List.tabulate(5)(_ + 1) val ys = xs.view map { x => println(x); x * x } 这不会打印任何内容,但每次访问列表都会执行计算并打印值,即每次调用ys.head都会打印1。如果您想再次获得该集合的严格版

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


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

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

以以下代码为例:

val xs = List.tabulate(5)(_ + 1)
val ys = xs.view map { x => println(x); x * x }
这不会打印任何内容,但每次访问列表都会执行计算并打印值,即每次调用
ys.head
都会打印
1
。如果您想再次获得该集合的严格版本,可以对其调用
force
。在这种情况下,您将看到打印出的所有数字

视图的一个用途是,当您需要遍历一组计算代价高昂的值,并且一次只需要一个值时。此外,视图还允许您通过对惰性序列调用
toStream
来构建惰性序列,该序列还将缓存已计算的元素。

请参阅

默认情况下,Scala集合在其所有转换器中都是严格的,除了
Stream
,后者惰性地实现其所有转换器方法。但是,有一种系统的方法可以将每个集合转换为惰性集合,反之亦然,这是基于集合视图的。视图是一种特殊的集合,它表示一些基本集合,但延迟地实现所有转换器

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

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


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

    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
Transform 1
Transform 2
Transform 3
Transform 4
Transform 5
found
而:

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

Transform 1
Transform 2
Transform 3
found
Transform 1
Transform 2
Transform 3
Transform 4
Transform 5
found

视图用于延迟计算,但不用于节省内存

针对集合创建视图时,已为该集合分配了内存


当使用
val view=Range(1,9).view创建视图时,
,集合已经分配了内存,如果它太大,比如
Range(11000000000)
,OOM不可避免

,这是一个非常说明性的视图使用案例。谢谢!