如何在 Kotlin 中停止使用 Stream.collect 并开始新生活
您是否曾从 Java 切换到 Kotlin,感觉像一条被冲上岸的鱼?尤其是在处理流时。在 Java 8 中,我们习惯了 .stream().filter().map().collect() 这样的链式调用。而在 Kotlin 中——啪!——熟悉的 Stream.collect 不见了。但别急着恐慌。实际上,Kotlin 标准库中拥有所有相同的功能,只是更方便、更简洁,没有多余的噪音。
在本文中,我们将详细讲解 Kotlin 中存在哪些 Java 8 Stream.collect 的等效方法,并通过实际示例进行演示。如果您正在寻找 "Kotlin 标准库中有哪些 Java 8 Stream.collect 的等效方法?" 这个问题的答案,那么您来对地方了。我们将涵盖最常用的操作:从简单的收集到列表,到复杂的分组和字符串拼接。
准备好了吗?开始吧!
1. 最简单的情况:toList() 和 toSet()
在 Java 中,要将流的结果收集到列表中,您会这样写:
List<String> result = list.stream() .filter(s -> s.length() > 3) .collect(Collectors.toList());在 Kotlin 中,这变成了一行代码,无需 collect:
val result = list.filter { it.length > 3 }是的,您没听错。Kotlin 中的 filter 已经返回一个列表。但如果您需要显式指定集合类型,请使用 toList()、toSet() 或 toMutableList():
val numbers = listOf(1, 2, 3, 4, 5, 5)val uniqueNumbers: Set<Int> = numbers.toSet()// 结果: [1, 2, 3, 4, 5]结论: 在 Kotlin 中,大多数集合操作(filter、map、flatMap)会直接返回一个列表。您不再需要 collect(Collectors.toList())。
2. 分组:groupingBy 替代 Collectors.groupingBy
分组是最常见的任务之一。在 Java 中,它看起来像这样:
Map<Integer, List<String>> byLength = list.stream() .collect(Collectors.groupingBy(String::length));在 Kotlin 中,有一个优雅的函数 groupBy:
val words = listOf("猫", "代码", "锅炉", "小猫")val byLength = words.groupBy { it.length }// 结果: {2=[猫], 4=[代码], 5=[锅炉], 4=[小猫]}但有一个细节:groupBy 直接返回 Map<K, List<V>>。如果您需要更复杂的操作,例如计算每个组中的元素数量呢?在 Java 中,您会使用 Collectors.counting():
Map<Integer, Long> countByLength = list.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting()));在 Kotlin 中,有 groupingBy + eachCount:
val countByLength = words.groupingBy { it.length }.eachCount()// 结果: {2=1, 4=2, 5=1}如果您需要收集的不是列表,而是集合呢?使用带转换的 groupBy:
val byLengthSet = words.groupBy(keySelector = { it.length }, valueTransform = { it.uppercase() })// 结果: {2=[猫], 4=[代码, 小猫], 5=[锅炉]}建议: 如果您需要介于 groupBy 和 groupingBy 之间的功能,请使用 groupingBy——它是惰性的,并允许应用不同的聚合操作(eachCount、fold、reduce)。
3. 字符串拼接:joinToString() 替代 Collectors.joining()
在 Java 中,使用分隔符拼接字符串:
String joined = list.stream() .collect(Collectors.joining(", "));在 Kotlin 中,这更简单:
val words = listOf("Kotlin", "Java", "Python")val joined = words.joinToString(",