我正在Scala中处理一个问题,其中我有两个输入Seq[Int]
,A
和B
,以及一个值函数f
,目标是找到A
和B
中任何一对元素(a, b)``f
。
我们可以用for-comprehension简单地做到这一点:
val A = Seq(1, 2, 3, 4, 5)
val B = Seq(6, 7, 8, 9, 10)
def f(a: Int, b: Int): Int = a * b // f can be more complex than just a multiplication. This is just an example.
val results = for {
a <- A
b <- B
} yield f(a, b)
results.max
字符串
我遇到的问题是A
和B
可能非常大,计算(a, b)
的每个组合都会导致内存错误。我实际上并不关心整个(a, b)
列表,甚至也不关心整个results
列表。我只关心最大值。
是否可以将for-comprehension生成的值列表流到f
中,然后再流到max函数中,这样我就不必在内存中保存整个列表了?
注记
- 我正在处理的问题是Leetcode #11 -最多水的容器。我知道线性时间解决方案,但我真正好奇的是,我们是否可以在Scala中将一个逻辑值序列流到聚合器函数中。
- 在我的研究中,我发现了scala
Streams
,它看起来像当前LazyList
类的前一个实现,但它们看起来不会给予我想要的行为。我不认为“流”是描述我在scala中想要的行为的合适的词,但我不确定下一步该搜索什么。
1条答案
按热度按时间6vl6ewon1#
我看了看评论,采取了实验性的方法。我启动了一个Scala shell并运行了以下两段代码。
使用
LazyList
:字符串
LazyList
不只是懒惰地计算集合,而且还试图保留它,这意味着集合将“泄漏”,即使这不是您正在寻找的行为。在我的测试运行中发生的情况是,进程从未用完内存(尽管我相信它最终会用完),但总是有一点内存需要回收,因此发生了如此多的垃圾收集,以至于进程实际上停止了有意义的进程。请参阅以下VisualVM内存监控图表:的数据
使用
Iterator
:型
Iterator
被 * 消耗 *(即有一个副作用),但不尝试记忆集合,这意味着可以收集已评估的项。这是在我的笔记本电脑上运行了几分钟。在VisualVM图表中可以看到内存是如何逐步消耗的,然后在“垃圾”开始堆积时回收:的