Ven*_*aju 71 iterable lazy-sequences kotlin
这两个接口都只定义了一种方法
public operator fun iterator(): Iterator<T>
Run Code Online (Sandbox Code Playgroud)
文档说Sequence
是懒惰的.但是也不是Iterable
懒惰(除非由a支持Collection
)?
hot*_*key 117
关键的区别在于语义和stdlib扩展函数的实现Iterable<T>
和Sequence<T>
.
因为Sequence<T>
,扩展函数尽可能延迟执行,类似于Java Streams 中间操作.例如,Sequence<T>.map { ... }
返回另一个Sequence<R>
,并且不实际处理的项目,直到一个终端等的操作toList
或fold
将被调用.
考虑以下代码:
val seq = sequenceOf(1, 2)
val seqMapped: Sequence<Int> = seq.map { print("$it "); it * it } // intermediate
print("before sum ")
val sum = seqMapped.sum() // terminal
Run Code Online (Sandbox Code Playgroud)
它打印:
before sum 1 2
Run Code Online (Sandbox Code Playgroud)
Sequence<T>
当您希望尽可能减少终端操作中完成的工作时,它适用于延迟使用和高效流水线操作,与Java Streams相同.然而,懒惰引入了一些开销,这对于较小集合的常见简单转换是不合需要的,并且使得它们的性能较差.
一般来说,没有好的方法可以确定何时需要它,所以在Kotlin中,stdlib懒惰被明确地提取并提取到Sequence<T>
界面以避免在Iterable
默认情况下在所有s 上使用它.
对于Iterable<T>
上相反,扩展功能的中间操作语义工作急切,过程中的项目马上和返回另一个Iterable
.例如,Iterable<T>.map { ... }
返回List<R>
带有映射结果的a .
Iterable的等效代码:
val lst = listOf(1, 2)
val lstMapped: List<Int> = lst.map { print("$it "); it * it }
print("before sum ")
val sum = lstMapped.sum()
Run Code Online (Sandbox Code Playgroud)
打印出:
1 2 before sum
Run Code Online (Sandbox Code Playgroud)
如上所述,Iterable<T>
默认情况下是非延迟的,并且这个解决方案很好地表现出来:在大多数情况下它具有良好的引用局部性,因此利用了CPU缓存,预测,预取等,因此即使多次复制集合仍然可以正常工作在小集合的简单情况下,足够并且表现更好.
如果您需要对评估管道进行更多控制,则可以使用Iterable<T>.asSequence()
函数显式转换为延迟序列.
Lea*_*ira 38
完成热键的答案:
重要的是要注意Sequence和Iterable如何在整个元素中迭代:
顺序示例:
list.asSequence()
.filter { field ->
Log.d("Filter", "filter")
field.value > 0
}.map {
Log.d("Map", "Map")
}.forEach {
Log.d("Each", "Each")
}
Run Code Online (Sandbox Code Playgroud)
记录结果:
过滤器 - 地图 - 每个; 过滤器 - 地图 - 每个
可重复的例子:
list.filter { field ->
Log.d("Filter", "filter")
field.value > 0
}.map {
Log.d("Map", "Map")
}.forEach {
Log.d("Each", "Each")
}
Run Code Online (Sandbox Code Playgroud)
过滤器 - 过滤器 - 地图 - 地图 - 每个 - 每个
归档时间: |
|
查看次数: |
9329 次 |
最近记录: |