Kotlin - 序列 Sequence

概念

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

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

创建

sequenceOf()

public fun <T> sequenceOf(vararg elements: T): Sequence<T> 

asSequence()

public fun <T> Iterable<T>.asSequence(): Sequence<T>

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

generateSequence()

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

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

constrainOnce()

public fun <T> Sequence<T>.constrainOnce(): Sequence<T>

一次性使用,只能迭代一次,超出一次报错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")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值