有人知道如何转换List
在Java中,我会使用如下格式:
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (c1, c2) -> {
List result = new ArrayList<>();
result.addAll(c1);
result.addAll(c2);
return result;
})
Kotlin是否有类似的设备,或者更好的?如有任何建议,不胜感激。
供您参考,Kotlin有一个toMap函数,在您不需要合并重复键的值的情况下。
然而,如果你想合并,你将不得不使用稍微复杂一点的方法。假设您有一个这样的对列表:
val pairs = listOf(
1 to listOf("1", "2", "3"),
1 to listOf("4"),
2 to listOf("1", "2", "3"),
3 to listOf("1", "2", "3"),
3 to listOf("4", "5", "6"),
)
你可以这样使用groupBy和mapValues:
val map = pairs.groupBy({ it.first }, { it.second })
.mapValues { (k, v) -> v.flatten() }
groupBy
将创建Map<Int, List<List<String>>>
,因此每个键将映射到与其对应的所有值的列表。然后mapValues
将每个列表的列表扁平化,使其成为单个列表。
注意,这会创建一个中间映射,与所提供的Java相比,在性能敏感的代码中可能不是很有效。如果您需要效率,您可以使用groupingBy来获得更惰性的分组,并按照您的意愿进行聚合。例如:
val map = pairs.groupingBy { it.first }
.fold(emptyList<String>()) { acc, v -> acc + v.second }
很好,但是在合并时会创建中间列表。或:
val map = pairs.groupingBy { it.first }.fold(
initialValueSelector = { _, _ -> mutableListOf<String>() },
operation = { _, acc, v -> acc.addAll(v.second); acc }
)
为每个键创建一个列表,但稍微复杂一些。如果你想变得更疯狂,也可以使用其他变体:
val map = pairs.groupingBy { it.first }.aggregate { k, acc: List<String>?, v, _ ->
if (acc == null) v.second else acc + v.second
}
(不可否认这有点拗口,并且仍然创建中间列表)
可以使用associate
进行隐蔽。比如:
listOf(
Pair(1, listOf("1", "2", "3")),
Pair(2, listOf("1", "2", "3")),
Pair(3, listOf("1", "2", "3"))
).associate { it.first to it.second }
结果是map:
{1=[1, 2, 3], 2=[1, 2, 3], 3=[1, 2, 3]}
如果只需要第一个元素作为值,则只需要修改映射到it.second.first()
的值。