假设我有一个昂贵的功能f
和许多值v
def f(x: Int) = {
x + 3
}
val v = 0 to 10e7.toInt
Run Code Online (Sandbox Code Playgroud)
现在,我想申请f
上v
,选择基于一定条件下的一些结果.
我可以这样做
v.map(f).filter(_ > 10e7 - 5)
Run Code Online (Sandbox Code Playgroud)
但这根本不可行,因为整体v.map(f)
将首先存储在内存中.
那么其他选择是:
for(a <- v if f(a) > 10e7 - 5) yield f(a)
Run Code Online (Sandbox Code Playgroud)
但是现在我需要为某些元素计算两次f,这是不可能的!
那么如何在不存储整个结果的情况下实现过滤,但仍能得到结果.逻辑看起来像这样(显然这不起作用):
for(a <- v) {
val b = f(a)
if(b > 10e7 - 5) yield b
}
Run Code Online (Sandbox Code Playgroud)
怎么样iterator
?
scala> v.iterator.map(f).filter(_ > 10e7 - 5).toVector
res4: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003)
Run Code Online (Sandbox Code Playgroud)
要么 view
scala> v.view.map(f).filter(_ > 10e7 - 5).toVector
res5: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003)
Run Code Online (Sandbox Code Playgroud)
两者都不会创建任何中间集合.
顺便说一句,不要在理解中寻找一些魔力,它们只是语法糖,你可以用这个做大致相当的事情:
scala> (for {
a <- v.iterator
fa = f(a)
if fa > 10e7 - 5
} yield fa).toVector
res9: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003)
Run Code Online (Sandbox Code Playgroud)
如果你不能iterator
从v
映射中获得整个集合仍然会在你的示例中出现OutOfMemoryError
.
归档时间: |
|
查看次数: |
42 次 |
最近记录: |