在kotlin中处理流
- Kotlin如何运行以下代码?
- 将5000000个整数的集合创建为临时集合还是将filter将其结果立即送到
forEach
,这意味着只有20个整数将被查看? - 如果不是,我将如何能够避免中间收集?
码:
class Tests { @Test fun test() { var counter = 0 (1..10_000_000).filter { it % 2 == 1 }.forEach { counter++ if (counter > 10) return } } }
您的代码示例使用Iterable
,该操作是热切的: .filter { ... }
调用将处理整个范围并生成一个存储中间结果的列表。
为了改变这种情况,可以考虑使用Sequence
(例如,使用.asSequence()
)来延迟工作,以便像.filter { ... }
这样的中间操作产生另一个懒惰的序列,并且只有在项目被查询终端操作如.forEach { ... }
:
(1..10000000).asSequence() .filter { it % 2 == 1 } .forEach { /* ... */ }
请参阅: Kotlin的Iterable和Sequence看起来完全一样。 为什么需要两种types?
通过将println(it)
添加到filter
您可以很快地看到问题的答案:
//... .filter { println(it) it % 2 == 1 } //...
你会看到每个打印的号码。 那是因为你的处理工作正如这里所说的那样急切地工作着。
正如已经提到的,懒序列拯救: (1..10_000_000).asSequence()
现在, filter
的println(it)
将只打印数字1..21
,这在你的例子中是非常可取的。