如下所示,我可以使用List<Int?>
函数将List<Int>
转换为mapNotNull
。
@Test
fun main() {
val testData = listOf(1, null, 3, null)
val noNull = processAwayNull(testData)
}
private fun processAwayNull(testData: List<Int?>): List<Int> {
return testData.mapNotNull{ it }
}
如何将Map<String, Int?>
转换为Map<String, Int>
?
下面的testData.filter { it.value != null }
无效,因为它仍会产生Map<String, Int?>
。
@Test
fun main() {
val testData = mapOf("One" to 1, "Two" to null, "Three" to 3, "Four" to null)
val noNull = processAwayNull(testData)
}
private fun processAwayNull(testData: Map<String, Int?>): Map<String, Int> {
return testData.filter { it.value != null }
}
答案 0 :(得分:4)
嗯,不是真的开箱即用(从某种意义上说,您立即获得Map<String, Int>
),但是filterValues
呢?
testData.filterValues { it != null } // gives Map<String, Int?> but without null-values
将其与mapValues
组合或替换(也许您可以使用默认值代替null
?)
// combining:
testData.filterValues { it != null }
.mapValues { (_, value) -> value as Int }
// replacing:
testData.mapValues { (_, value) -> value ?: /* default value */ 0 }
两者都给出了Map<String, Int>
,但是第一个创建并填充了2个地图,第二个使用0
而不是null
。
您还可以使用适当的filterValues
来简化unchecked cast变量,因为“我们知道的更好”:
testData.filterValues { it != null } as Map<String, Int> // unchecked cast, because: we really do know better, do we? ;-)
或者,您也可以按照已知的方式处理所有条目(使用mapNotNull
),然后根据它创建一个新地图:
testData.asSequence()
.mapNotNull { (key, value) ->
value?.let {
key to it
}
}
.toMap() // giving Map<String, Int>
如果您需要更多的时间,您甚至可能希望拥有自己的扩展功能:
@Suppress("UNCHECKED_CAST")
fun <K, V> Map<K, V?>.filterValuesNotNull() = filterValues { it != null } as Map<K, V>
现在您可以按如下方式使用它:
testData.filterValuesNotNull() // giving Map<String, Int>