使用哈希映射键的智能投射
Smart Cast with hashmap keys
我正在将一些 Java 应用程序移植到 Kotlin,并且我将 运行 用于哈希映射的这个问题。假设我有两个哈希图:
var firstHashmap: HashMap<String, String> = hashMapOf("foo" to "A", "bar" to "B")
var secondHashmap: HashMap<String, String> = hashMapOf("foo" to "C", "bar" to "D")
如果另一个中存在相同的密钥,我想更新一个:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"]
}
Kotlin 不会编译第二行,因为 firstHashmap
不能保证有一个“foo”键。我只是在第一行检查它并不重要——智能转换系统显然不适用于散列映射键。这有同样的问题:
if (firstHashmap.containsKey("foo")) {
secondHashmap["foo"] = firstHashmap["foo"]
}
这可行,但在某些情况下创建额外变量会变得混乱:
val newValue = firstHashmap["foo"]
if (newValue != null) {
secondHashmap["foo"] = newValue
}
这也有效,但到目前为止我从来没有使用过 !!
修饰符:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"]!!
}
这行得通,但是永远不会使用 Elvis 运算符之后的默认值,只是为了满足编译器的要求,感觉不对:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"] ?: ""
}
更进一步,我尝试放弃条件并仅使用 Elvis 运算符,但随后它卡在 secondHashMap
没有保证的密钥:
secondHashmap["foo"] = firstHashmap["foo"] ?: secondHashmap["foo"]
那么这会起作用,但这让我回到添加默认值只是为了欺骗编译器:
secondHashmap["foo"] = firstHashmap["foo"] ?: secondHashmap["foo"] ?: ""
有没有更好的方法来处理这个问题,比如触发智能投射系统知道钥匙真的在那里?否则,我猜 !!
选项似乎是最干净的,尤其是当我从上一行中清楚地看出我选择使用它的原因时。
无法保证 firstHashmap["foo"]
returns 每次调用时都具有相同的值。智能转换仅限于保证不会更改的内容,例如 val
本地模块中没有自定义 getter。
您可以使用
firstHashmap["foo"]?.let {
secondHashmap["foo"] = it
}
仅在 secondHashmap
不为空时设置值。
我正在将一些 Java 应用程序移植到 Kotlin,并且我将 运行 用于哈希映射的这个问题。假设我有两个哈希图:
var firstHashmap: HashMap<String, String> = hashMapOf("foo" to "A", "bar" to "B")
var secondHashmap: HashMap<String, String> = hashMapOf("foo" to "C", "bar" to "D")
如果另一个中存在相同的密钥,我想更新一个:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"]
}
Kotlin 不会编译第二行,因为 firstHashmap
不能保证有一个“foo”键。我只是在第一行检查它并不重要——智能转换系统显然不适用于散列映射键。这有同样的问题:
if (firstHashmap.containsKey("foo")) {
secondHashmap["foo"] = firstHashmap["foo"]
}
这可行,但在某些情况下创建额外变量会变得混乱:
val newValue = firstHashmap["foo"]
if (newValue != null) {
secondHashmap["foo"] = newValue
}
这也有效,但到目前为止我从来没有使用过 !!
修饰符:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"]!!
}
这行得通,但是永远不会使用 Elvis 运算符之后的默认值,只是为了满足编译器的要求,感觉不对:
if (firstHashmap["foo"] != null) {
secondHashmap["foo"] = firstHashmap["foo"] ?: ""
}
更进一步,我尝试放弃条件并仅使用 Elvis 运算符,但随后它卡在 secondHashMap
没有保证的密钥:
secondHashmap["foo"] = firstHashmap["foo"] ?: secondHashmap["foo"]
那么这会起作用,但这让我回到添加默认值只是为了欺骗编译器:
secondHashmap["foo"] = firstHashmap["foo"] ?: secondHashmap["foo"] ?: ""
有没有更好的方法来处理这个问题,比如触发智能投射系统知道钥匙真的在那里?否则,我猜 !!
选项似乎是最干净的,尤其是当我从上一行中清楚地看出我选择使用它的原因时。
无法保证 firstHashmap["foo"]
returns 每次调用时都具有相同的值。智能转换仅限于保证不会更改的内容,例如 val
本地模块中没有自定义 getter。
您可以使用
firstHashmap["foo"]?.let {
secondHashmap["foo"] = it
}
仅在 secondHashmap
不为空时设置值。