Java 8 中的 stream.collect(Collectors.toMap()) 在 Kotlin 中的类比

14
假设我有一个人员名单,并且想要一个类型为Map<String, Person>的映射表,其中字符串是人名。我应该如何在Kotlin中实现这个呢?

相关内容:https://dev59.com/HFsW5IYBdhLWcg3wuZVy - Duncan McGregor
1
相关链接:https://dev59.com/v1sW5IYBdhLWcg3wuZRy - Jayson Minard
2个回答

24
假设您已经具备。
val list: List<Person> = listOf(Person("Ann", 19), Person("John", 23))

associateBy函数可能会满足您的需求:

val map = list.associateBy({ it.name }, { it.age })
/* Contains:
 * "Ann" -> 19
 * "John" -> 23
*/

如KDoc所述,associateBy

返回一个Map,该Map由给定数组的元素经过keySelector函数和valueTransform函数处理后得到的键值对组成。

如果有两个或多个元素的keySelector函数返回相同的键,则只会将最后一个元素添加到Map中。

返回的Map保留原始数组的迭代顺序。

associateBy适用于任何Iterable


在当前的 Kotlin 中,toMap() 已经更改为 toMapBy(),请您更新答案。 - Jayson Minard
有关Stream.collect和Kotlin之间的其他等效方法,请参见https://dev59.com/v1sW5IYBdhLWcg3wuZRy - Jayson Minard
@JaysonMinard,谢谢,已更新答案,并使用了另一个toMapBy重载,它更接近于Collectors.toMap - hotkey
1
找不到 List.toMapBy... 可能是缺少了一个导入。然而,.keysToMap {transform(it)} 正是我要用来替换 .stream().collect(Collectors.toMap(Function.identity(), {transform(it)})) 的东西。 - TWiStErRob
@TWiStErRob,toMapBy函数似乎已经更名为associateBy。感谢您的注意,我会更新答案。 - hotkey
实际上,不要使用keysToMapassociateBy(identity(), {...})associateBy可以,identity()不行!)这两个函数都是Jetbrains内部的函数(org.jetbrains.kotlin.utils),而不是公共的Kotlin API(kotlin.*)。它们通过gradle-kotlin-dslkotlin-compiler-embeddable引入。依赖这些函数可能会导致ClassNotFoundExceptions异常。 - TWiStErRob

4

Kotlin 提供了许多替代方案 :)

val x: Map<String, Int> = list.associate { it.name to it.age }
val y: Map<String, Int> = list.map { it.name to it.age }.toMap()
var z: Map<String, Int> = list.associateBy({ it.name }, { it.age })

在我看来,针对这种情况最好的选择是第一种方式,因为不需要使用 Lambda,只需进行简单的转换即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接