Kotlin 收集以映射跳过的空值

Kotlin 收集以映射跳过的空值,kotlin,Kotlin,如何从排除/跳过空值的列表中收集到映射 此代码不会跳过空值: val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null)) .associateBy({ it.first }, { it.second }) println(map) 解决方案。但收集到可变地图中: val map2 = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), P

如何从排除/跳过空值的列表中收集到映射

此代码不会跳过空值:

val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
    .associateBy({ it.first }, { it.second })
println(map)
解决方案。但收集到可变地图中:

val map2 = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
    .mapNotNull {
        if (it.second != null) it else null
    }.toMap()    
println(map2)

那么有没有更方便的方法呢?另外,我想获得
Map
类型,而不是
Map

如果要筛选出
null
值,则应使用
filter
方法:

val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
    .filter { it.second != null }
    .toMap()
println(map)

实际上,对pwolaq的答案稍作修改就可以保证第二项不可为空:

val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
    .mapNotNull { p -> p.second?.let { Pair(p.first, it) } }
    .toMap()
println(map)
这将为您提供一个
Map
,因为
mapNotNull
忽略映射到
null
的任何内容,并使用
let
和安全呼叫操作符
?。
如果其接收器(
p.second
)为
null
,则返回null


这基本上就是您在问题中所说的,使用
let

将其缩短。更具可读性的解决方案可能是将associateBy函数与双爆炸表达式一起使用(!!):

val-map:map=listOf(
对(“a”,1),
对(“b”,空),
对(“c”,3),
配对(“d”,空)
)
.filter{it.first!=null&&it.second!=null}
.associateBy({it.first!!},{it.second!!})
println(地图)

如果使用toMap()而不是associateBy()怎么办?至少Java生成的代码更短。协会()生成多余的对,但我们已经有了它们。此外,您的代码返回可空类型的映射,即不是
Map
,而是
Map
@EldarAgalarov如果您想在此处具有不可空类型,则必须自己强制转换值
mapNotNull
在此处没有意义,因为它检查
对是否不可用
null
@pwolaq如果您查看传递给
mapNotNull
的lambda,这不是真的。您所说的“收集到可变映射”是什么意思
toMap
返回一个
Map
,而不是
MutableMap
@Moira您是对的,我没有查找引用,我认为
mapNotNull
只是跳过
null
值并对其余值应用转换
val map: Map<String, Int> = listOf(
        Pair("a", 1),
        Pair("b", null),
        Pair("c", 3),
        Pair("d", null)
)
.filter { it.first != null && it.second != null }
.associateBy({ it.first!! }, { it.second!! })

println(map)