当前位置: 首页 > news >正文

Kotlin序列

序列(Sequences)

序列是一种容器,其中的对象不是事先存储的,而是在迭代过程中动态生成的。 这意味着这些对象只有在真正需要使用时才会被处理:也就是说,序列是惰性执行的(lazy evaluation),每一步不会立刻产生中间结果。

序列提供了与 Iterable 相同的函数:我们可以对其进行过滤、映射、排序等操作,但在底层的实现方式上有所不同。对于 Iterable,每一步操作都对整个集合执行并返回一个新的中间集合;而对于 Sequence,每个操作都是逐个元素地链式执行,直到最终结果被请求时才真正开始处理。

这带来了两个优势:

  1. 序列可以是无限的:我们可以通过初始值和一个函数来定义一个序列,例如无限增长的数列。

  2. 避免中间集合的创建:多个操作(如过滤、转换等)在序列中是链式按需执行的,不需要每一步都生成新的集合。


创建序列的方法

1. 从元素创建

使用 sequenceOf() 函数,从给定的元素生成序列:

val sequenceOfStrings = sequenceOf("one", "two", "three", "four")
val sequenceOfInts = sequenceOf(1, 2, 3, 4)

2. 从可迭代对象(Iterable)创建

可以使用 asSequence() 将任何集合转换为序列:

val listOfStrings = listOf("one", "two", "three", "four")
val listOfInts = listOf(1, 2, 3, 4)val sequenceOfStrings = listOfStrings.asSequence()
val sequenceOfInts = listOfInts.asSequence()

解释:这会将已有的 List 或其他集合转换为 Sequence,以便惰性处理元素。


3. 从函数创建

使用 generateSequence(),它接收一个初始值(种子)和一个函数,根据规则生成一个(可能无限的)序列:

val sequenceOfEvenNumbers = generateSequence(1) { it + 1 }.filter { it % 2 == 0 }.take(5)
println(sequenceOfEvenNumbers.toList()) // [2, 4, 6, 8, 10]

解释:这段代码生成了一个从 1 开始不断加 1 的序列,过滤出偶数,并取前 5 个。


4. 从代码块分块生成

使用 sequence {} 代码块,配合 yield()yieldAll() 按需产生元素:

val evenNumbersSequence = sequence {yield(2)yieldAll(listOf(4, 6))yieldAll(generateSequence(8) { it + 2 })
}
println(evenNumbersSequence.take(5).toList()) // [2, 4, 6, 8, 10]

解释:这个序列依次生成了 2,4,6,然后从 8 开始生成无限个偶数。


一、序列操作的两大分类:无状态 vs 有状态

无状态操作(Stateless)

定义:对每个元素独立处理,不依赖之前元素或上下文。

方法用途示例代码
map()对每个元素应用变换sequenceOf(1, 2, 3).map { it * 2 }[2, 4, 6]
filter()过滤符合条件的元素sequenceOf(1, 2, 3, 4).filter { it % 2 == 0 }[2, 4]
take(n)取前 n 个元素sequenceOf(1, 2, 3, 4).take(2)[1, 2]
drop(n)跳过前 n 个元素sequenceOf(1, 2, 3, 4).drop(2)[3, 4]
这些操作通常开销较小,并且可以尽早终止处理。

有状态操作(Stateful)

定义:需要维护中间状态(缓存、计数、排序等),通常必须遍历整个序列。

方法用途示例代码
sorted()排序(需收集全部元素)sequenceOf(3, 1, 2).sorted()[1, 2, 3]
distinct()去重(需跟踪已出现的值)sequenceOf(1, 2, 1).distinct()[1, 2]
chunked(n)将序列划分为多个块sequenceOf(1,2,3,4,5).chunked(2)[[1,2], [3,4], [5]]

二、序列操作的阶段:中间 vs 终端

中间操作(Intermediate)

特点:惰性执行,不立刻处理元素,只是构造操作链。返回新的 Sequence

方法用途示例
map()转换元素sequence.map { it * 2 }
filter()过滤元素sequence.filter { it > 0 }
take() / drop()取/跳前几个sequence.take(3)
sorted()排序sequence.sorted()
这些方法只有在终端操作触发时才执行!

终端操作(Terminal)

特点:触发执行,返回结果(如集合、单个值等),整个序列会被遍历或处理。

方法用途示例返回值类型
toList()转换为 Listsequence.toList()List<T>
sum()求和sequenceOf(1,2,3).sum()Int
count()元素个数sequence.count()Int
first() / last()获取首/尾元素sequence.first()T
forEach()遍历每个元素sequence.forEach { println(it) }Unit
reduce() / fold()累加/聚合sequence.reduce { acc, e -> acc + e }T

三、完整示例:理解延迟执行与触发机制

fun main() {val result = sequenceOf(1, 2, 3, 4, 5).map {println("map $it")it * 2}.filter {println("filter $it")it > 5}.take(2) // 限制只取前两个符合条件的元素.toList() // 触发执行println("Result: $result")
}

序列与集合的处理方式对比

Iterable急切(eager)执行

每个操作都在所有元素上执行,并产生中间集合。

val withIterator = (1..10).filter { print("Filter: $it, "); it % 2 == 0 }.map { print("Mapping: $it, "); it * 2 }.take(3)println()
// 输出:
// Filter: 1, Filter: 2, ... Filter: 10,
// Mapping: 2, Mapping: 4, Mapping: 6, Mapping: 8, Mapping: 10
// 结果:[4, 8, 12]

总共执行了:

  • 10 次 filter

  • 5 次 map

  • 3 次 take
    总计:18 次操作


Sequence惰性(lazy)执行

每个元素在执行链中逐个被处理,没有中间集合。

val withSequence = (1..10).asSequence().filter { print("Filter: $it, "); it % 2 == 0 }.map { print("Mapping: $it, "); it * 2 }.take(3).toList()println()
// 输出:
// Filter: 1, Filter: 2, Mapping: 2, Filter: 3, Filter: 4, Mapping: 4, ...
// 结果:[4, 8, 12]

📊 总共执行了:

  • 6 次 filter

  • 3 次 map

  • 3 次 take
    总计:12 次操作


总结

Sequences(序列) 提供了强大且高效的方式来处理数据集合,特别适合于:

  • 大型集合或数据流

  • 多步链式处理的场景

  • 惰性处理需求

  • 表达无限序列或生成序列的逻辑

当你需要优化集合操作性能时,考虑使用 Sequence 是一个很好的选择。

http://www.lryc.cn/news/592032.html

相关文章:

  • CloudFabric解决方案
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • HTTP 性能优化:五条建议
  • 线程安全集合——ConcurrentHashMap
  • 微店平台商品详情接口技术实现指南
  • 前端埋坑之js console.log字符换行后 html没换行问题处理
  • javascript 中数组对象操作方法
  • AE PDW2200电源射频手侧使用安装说明含电路图
  • 自学力扣:最长连续序列
  • CSS样式中的布局、字体、响应式布局
  • AI大模型打造金融智能信审助手04.七大金融监管相关政策
  • 【Oracle】centos7离线静默安装oracle11g(p13390677_112040)
  • 智象科技赋能金融、证券行业 IT 运维
  • PostgreSQL 16 Administration Cookbook 读书笔记:第7章 Database Administration
  • 【git仓库搭建笔记】
  • Oracle 19C 后台主要进程的功能解析
  • CertiK创始人顾荣辉出席上海Conflux大会,聚焦Web3全球化中的安全与合规路径
  • 赛思SLIC芯片、语音芯片原厂 赛思SLIC语音芯片ASX630:国产强“芯”赋能FTTR全光网络​
  • Docker Swarm 集群使用记录
  • 基于LiteNetLib的Server/Client Demo
  • 算法训练营day24 回溯算法③ 93.复原IP地址 、78.子集、 90.子集II
  • 零基础入门:用C++从零实现TCP Socket网络小工具
  • 人脸检测算法——SCRFD
  • Ubuntu系统下快速体验iperf3工具(网络性能测试)
  • 2G和3G网络关闭/退网状态(截止2025年7月)
  • Python技术题1
  • 【RK3576】【Android14】开发环境搭建
  • 基于现代R语言【Tidyverse、Tidymodel】的机器学习方法与案例分析
  • 用 React-Three-Fiber 实现雪花下落与堆积效果:从零开始的 3D 雪景模拟
  • 前端迟迟收不到响应,登录拦截器踩坑!