Kotlin - 序列 Sequence

概念

虽然Kotlin中的集合支持链式调用,但是序列才类似于Java中的Stream,只是没有parallel模式。一样是操作分为三步:创建序列、中间操作、终止操作。

  • 中间操作符通过序列嵌套,实现对迭代器iterator的嵌套。这样在进行迭代的时候,会依次调用各个iterator迭代器直到调用到原始集合数据里的迭代器开始并返回元素。而当元素返回时,会依次执行各个迭代器持有变换操作方法实现对数据的变换。
  • 中间操作符并不负责开启迭代器,以此实现惰性操作且不产生临时集合。末端操作符负责开启迭代,按照嵌套顺序执行迭代操作。依次获取操作后的数据,并且会创建新的集合用来存储最终数据。
区别 Sequence Iterable
数据的操作 延迟的,用新的操作符装饰前一个(装饰者模式),只有在结果被请求时才执行起来(较大集合或复杂计算的时候使用)。 即时的,每一步都会创建一个中间集合,后续操作都在这个集合上继续执行。迭代次数意味着性能损耗。
操作符的执行顺序 单个元素完成所有操作后,再进行下一个元素(对结果只取前N个优势明显)。 对所有元素完成操作,再进行下一步操作。
选择 选择 Sequence 选择 Iterable
操作步骤
计算后取少量元素 性能高 性能低
倒序操作
索引访问

创建

sequenceOf()

public fun sequenceOf(vararg elements: T): Sequence 

asSequence()

public fun Iterable.asSequence(): Sequence

使用 Iterable 的扩展函数来创建。

generateSequence()

public fun generateSequence(nextFunction: () -> T?): Sequence
public fun generateSequence(seed: T?, nextFunction: (T) -> T?): Sequence
public fun generateSequence(seedFunction: () -> T?, nextFunction: (T) -> T?): Sequence

nextFunction用来生成元素,必须在某个情况下返回null来停止生成,否则报错OutOfMemoryError。seedFunction和seed都是初始值,一个直接指明,一个调用函数获取。

constrainOnce()

public fun Sequence.constrainOnce(): Sequence

一次性使用,只能迭代一次,超出一次报错IllegalStateException。

val generateSequenceOne = generateSequence { 3 }
val generateSequenceTwo = generateSequence(0) {if (it < 100) it + 1 else null}  //此处的it是上一个元素
val generateSequenceThree = generateSequence({ 0 }) { if (it < 100) it + 1 else null }  //此处的it是上一个元素
//Sequence耗时:23:[-1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37]
val sequenceTime = System.currentTimeMillis()
val list1 = (0..10000000).asSequence().map { it * 2 }.map { it - 1 }.take(20).toList()
println("Sequence耗时:${System.currentTimeMillis() - sequenceTime}:$list1")
//List耗时:5489:[-1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37]
val listTime = System.currentTimeMillis()
val list2 = (0..10000000).map { it * 2 }.map { it - 1 }.take(20).toList()
println("List耗时:${System.currentTimeMillis() - listTime}:$list2")

你可能感兴趣的:(Kotlin,kotlin)