在 Java 8 中,有 Stream.collect
允许对集合进行聚合。在 Kotlin 中,这并不以相同的方式存在,除了可能作为 stdlib 中的扩展函数的集合。但尚不清楚不同用例的等价物是什么。
例如,在 Collectors
的 JavaDoc 的顶部是 为 Java 8 编写的示例,当将它们移植到 Kolin 时,您不能在不同的 JDK 版本上使用 Java 8 类,因此它们很可能应该写成不同的。
就显示 Kotlin 集合示例的在线资源而言,它们通常是微不足道的,并不能真正与相同的用例进行比较。什么是真正匹配 Java 8 Stream.collect
记录的案例的好例子?那里的清单是:
- 将名称累积到列表中
- 将名称累积到 TreeSet 中
- 将元素转换为字符串并连接它们,以逗号分隔
- 计算雇员的工资总和
- 按部门分组员工
- 按部门计算工资总和
- 将学生分为合格和不合格
在上面链接的 JavaDoc 中有详细信息。
注意: 这个问题是作者有意编写和回答的( 自 答题),因此常见的 Kotlin 主题的惯用答案出现在 SO 中。还要澄清一些为 Kotlin alpha 编写的非常古老的答案,这些答案对于当今的 Kotlin 来说并不准确。
原文由 Jayson Minard 发布,翻译遵循 CC BY-SA 4.0 许可协议
Kotlin stdlib 中有用于平均、计数、不同、过滤、查找、分组、连接、映射、最小值、最大值、分区、切片、排序、求和、到/从数组、到/从列表、到/从映射的函数、联合、协同迭代、所有功能范式等等。因此,您可以使用它们来创建小的 1-liner,而无需使用 Java 8 的更复杂语法。
我认为内置的 Java 8
Collectors
类中唯一缺少的是总结(但在 这个问题的另一个答案中 是一个简单的解决方案) 。两者都缺少一件事是按计数进行批处理,这在 另一个 Stack Overflow 答案 中可以看到,并且也有一个简单的答案。另一个有趣的案例也是来自 Stack Overflow 的案例: Idiomatic way to spilled sequence into three lists using Kotlin 。如果您想出于其他目的创建类似
Stream.collect
的内容,请参阅 Kotlin 中的 Custom Stream.collect2017 年 8 月 11 日 编辑: 在 kotlin 1.2 M2 中添加了分块/窗口化收集操作,请参阅 https://blog.jetbrains.com/kotlin/2017/08/kotlin-1-2-m2-is-out/
在创建可能已经存在的新函数之前,从整体上探索 kotlin.collections 的 API 参考 总是好的。
以下是从 Java 8
Stream.collect
到 Kotlin 中等效项的一些转换示例:将名称累积到列表中
将元素转换为字符串并连接它们,以逗号分隔
计算雇员的工资总和
按部门分组员工
按部门计算工资总和
将学生分为合格和不合格
男性成员姓名
名册中成员的组名(按性别)
将列表过滤到另一个列表
寻找最短的字符串列表
应用过滤器后对列表中的项目进行计数
然后继续……在所有情况下,不需要特殊的折叠,减少或其他功能来模仿
Stream.collect
。如果您有更多用例,请在评论中添加它们,我们可以看到!关于懒惰
如果你想延迟处理一个链,你可以在链之前使用
asSequence()
转换为Sequence
。在函数链的末尾,您通常也会得到Sequence
。 Then you can usetoList()
,toSet()
,toMap()
or some other function to materialize theSequence
at the end.为什么没有类型?!?
您会注意到 Kotlin 示例没有指定类型。这是因为 Kotlin 具有完整的类型推断并且在编译时是完全类型安全的。比 Java 更重要,因为它还具有可为 null 的类型,并且可以帮助防止可怕的 NPE。所以在 Kotlin 中是这样的:
是相同的:
Because Kotlin knows what
people
is, and thatpeople.age
isInt
therefore the filter expression only allows comparison to anInt
, and thatpeople.name
is aString
therefore themap
step produces aList<String>
(readonlyList
ofString
)。现在,如果
people
可能是null
,如List<People>?
那么:返回一个
List<String>?
需要进行空检查( _或使用其他 Kotlin 运算符之一来获取可空值,请参阅此 Kotlin idiomatic way to deal with nullable values 以及 Idiomatic way of handling nullable or empty list in科特林_)也可以看看: