【发布时间】:2016-07-26 15:38:41
【问题描述】:
如果我有一个 immutableMap: Map<String, Int> 并想将其转换为 mutableMap: MutableMap<String, Int>,那么最好的方法是什么?好像没有什么方便的方法。
【问题讨论】:
标签: kotlin
如果我有一个 immutableMap: Map<String, Int> 并想将其转换为 mutableMap: MutableMap<String, Int>,那么最好的方法是什么?好像没有什么方便的方法。
【问题讨论】:
标签: kotlin
更新: Kotlin 1.1 标准库有一个.toMutableMap() 函数。应该使用它而不是创建自己的。
------------------------ 下面的旧答案---------- ---------
以下扩展功能通过将Map 复制到MutableMap 来工作。
fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> {
return HashMap(this)
}
其他一些答案建议检查地图是否为MutableMap,如果是则转换为它。应该不惜一切代价避免这种情况,因为这是一种不好的做法。在 Kotlin 中它被向下转换为 Map 的事实意味着不应更改此 Map,这样做会很危险。
【讨论】:
首先,正如之前关于 Kotlin 只读集合及其不变性的问题所述,它们实际上是可能的可变集合的只读实时视图。
Kotlin 可以安全地检查这些类型的可变性,因为接口上有标记让 Kotlin 知道,例如:
// assuming some variable readOnlyMap of type Map<String, String>
val mutableMap: MutableMap<String, String> = if (readOnlyMap is MutableMap<*,*>) {
readOnlyMap as MutableMap
} else {
HashMap(readOnlyMap)
}
这个is 检查内部调用TypeIntrinsics.isMutableMap 并且是知道它是否可转换的有效方法。如果您先进行此检查,则演员表中没有危险。您会注意到编译器非常高兴并且没有警告。如果您不打算修改被视为只读的同一张地图,这可能会很危险,但表明您可以强制施放影响。
如果您不想修改原始地图,那么当然总是通过简单地使用另一个地图HashMap(readOnlyMap) 调用 HashMap 的构造函数来制作副本。或者做一个扩展函数:
fun <K, V> Map<K, V>.toMutableCopy() = HashMap(this)
然后调用它:
val mutableMap = readOnlyMap.toMutableCopy()
现在你有了简单的方法。
另请参阅:
【讨论】:
is MutableMap 检查,因为它可以为实际上不可变的 Java 集合返回 true。例如尝试Collections.unmodifiableMap(mutableMapOf("a" to "b")) is MutableMap<*,*>。
HashMap 的示例(我相信mutableMapOf 实际上使用LinkedHashMap)。例如:val mutableMap = map.entries.associateTo(mutableMapOf()) { entry -> entry.toPair() }.