Kotlin的Iterable和Sequence看起来完全一样。 为什么需要两种类型?

这两个接口都只定义了一种方法

public operator fun iterator(): Iterator<T> 

文件说Sequence是懒惰的。 但是也不是可以Iterable懒(除非有一个Collection支持)?

  • 如何在Kotlin中使用Swagger @ApiResponses注解?
  • 为什么@Primary有时候不适用于Kotlin类?
  • Vertx已经写过“回复”
  • AndroidStudio ExternalSystemException与kotlin 0.12.213
  • SwipeRefreshLayout和RecyclerView之间的差距
  • 如何使用Lamba表达式使Java方法调用在Kotlin中不那么冗长?
  • Kotlin:如何inheritance数据类中的属性
  • Java / Kotlin JSON解析改进
  • One Solution collect form web for “Kotlin的Iterable和Sequence看起来完全一样。 为什么需要两种类型?”

    关键的区别在于Iterable<T>Sequence<T>的stdlib扩展函数的语义和实现。

    • 对于Sequence<T> ,扩展函数在可能的情况下执行延迟,类似于Java Streams 中间操作。 例如, Sequence<T>.map { ... }返回另一个Sequence<R> ,实际上并不处理这些项目,直到调用像toListfold这样的终端操作为止。

      考虑这个代码:

       val seq = sequenceOf(1, 2) val seqMapped: Sequence<Int> = seq.map { print("$it "); it * it } print("before sum ") val sum = seqMapped.sum() 

      它打印:

       before sum 1 2 

      当您想要尽可能减少在终端操作中完成的工作时, Sequence<T>用于惰性使用和高效管道,与Java Streams相同。 然而,懒惰引入了一些开销,这对于较小集合的常见简单转换是不可取的,并且使得它们性能较差。

      一般来说,没有什么好的方法来确定什么时候需要它,所以在Kotlin中stdlib懒惰是明确的,并提取到Sequence<T>接口,以避免在所有的Iterable默认使用它。

    • 对于Iterable<T> ,相反,具有中间操作语义的扩展函数急切地工作,立即处理项目并返回另一个Iterable 。 例如, Iterable<T>.map { ... }返回一个带有映射结果的List<R>

      Iterable的等效代码:

       val lst = listOf(1, 2) val lstMapped: List<Int> = lst.map { print("$it "); it * it } print("before sum ") val sum = lstMapped.sum() 

      这打印出来:

       1 2 before sum 

      如上所述,默认情况下, Iterable<T>是非惰性的,这个解决方案很好地展示了它:在大多数情况下,它具有良好的参考局部性,从而利用CPU缓存,预测,预取等优势,收集仍然工作得很好,并在小集合的简单情况下表现更好。

      如果您需要对评估流水线进行更多的控制,则会使用Iterable<T>.asSequence()函数显式转换为惰性序列。

    Kotlin language will be the best programming language for Android.