![](/img/trans.png)
[英]How can I create a Map with non-null values from a set of nullable items in Kotlin?
[英]how to elegantly create a map with only non-null values in Kotlin
如何在不必求助于 MutableMap 并转换为不可变 map 的情况下重写此代码?
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val map = mutableMapOf("key1" to mandatoryValue)
optionalValue?.let { map.put("key2", it) }
return map.toMap()
}
我的替代解决方案也不是很好,因为它需要一个不安全的演员表:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf(
"key1" to mandatoryValue,
"key2" to optionalValue
).filterValues { it != null } as Map<String, String>
我正在寻找的是以下内容:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf(
"key1" to mandatoryValue,
optionalValue?.let { "key2" to it }
)
您可以拥有自己的扩展 function 如下,然后使用它从Map
过滤 null 值:
fun <K, V> Map<K, V?>.filterValuesNotNull() =
mapNotNull { (k, v) -> v?.let { k to v } }.toMap()
toMap()
不一定会创建不可变的 map。 它只保证是只读的。 底层 class 实例可能是一个 MutableMap(如果它有多个键,则在当前实现中为真)。 因此,您的第一个代码块中的toMap()
是不必要的。 当您返回 MutableMap 时,它会自动向上转换为 Map,因为您将 Map 指定为返回类型。 所以,你可以把
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val map = mutableMapOf("key1" to mandatoryValue)
optionalValue?.let { map.put("key2", it) }
return map
}
或者
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mutableMapOf("key1" to mandatoryValue).apply {
if (optionalValue != null) put("key2", optionalValue)
}
要获得您在上一个示例中请求的语法,您可以创建一个mapOf
重载,它接受并过滤 null 值:
fun <K, V> mapOf(vararg pairs: Pair<K, V>?): Map<K, V> =
mapOf(*pairs.filterNotNull().toTypedArray())
使用MutableMap
没有任何问题——事实上,您的第一个解决方案(没有多余的toMap()
)已经非常优雅了。 它比任何不可变的答案都更简单、更清晰。 不可变操作是以额外的 object 创建和复制为代价的,因此,除非您需要保证不变性,否则最好使用MutableMap
,但只能通过Map
接口公开它,就像您已经在做的那样。
如果你真的想一成不变地做到这一点,你可以这样做:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf("key1" to mandatoryValue) +
(optionalValue?.let { mapOf("key2" to it) } ?: emptyMap())
或者等效地,如果您愿意:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> =
mapOf("key1" to mandatoryValue) +
if (optionalValue != null) mapOf("key2" to optionalValue) else emptyMap()
或者:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val mandatoryMap = mapOf("key1" to mandatoryValue)
return optionalValue?.let { mandatoryMap + ("key2" to optionalValue) } ?: mandatoryMap
}
或者:
fun createMap(mandatoryValue: String, optionalValue: String?): Map<String, String> {
val mandatoryMap = mapOf("key1" to mandatoryValue)
return if (optionalValue != null) mandatoryMap + ("key2" to optionalValue) else mandatoryMap
}
在 kotlin 1.6
buildMap {
put("key1", mandatoryValue)
if (optionalValue != null)
put("key2", optionalValue)
}
这会在工作表下创建一个 mutableMap,但非常优雅且可读 <3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.