在Kotlin中将不可变映射复制到可变映射

spi*_*ce7 14 kotlin

如果我有immutableMap: Map<String, Int>并希望将其转换为a mutableMap: MutableMap<String, Int>,那么最好的方法是什么?似乎没有任何方便的方式.

spi*_*ce7 14

更新: Kotlin 1.1 stdlib有一个.toMutableMap()功能.应该使用它而不是创建自己的.

-----------------------下面的旧答案------------------------ ------

以下扩展功能通过复制Map到a来工作MutableMap.

fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> {
  return HashMap(this)
}
Run Code Online (Sandbox Code Playgroud)

其他一些答案建议检查地图是否为a MutableMap,然后如果是,则转换为地图.应该不惜一切代价避免这种情况,因为这是一种不好的做法.它被MapKotlin中的一个事实所暗示,这意味着它Map不应该被改变,这样做会很危险.


Jay*_*ard 9

首先,正如之前关于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)
}
Run Code Online (Sandbox Code Playgroud)

is内部调用此检查TypeIntrinsics.isMutableMap是一种有效的方法,可以知道它是否可以转换.如果您先进行此检查,则演员阵容中没有任何危险.你会注意到编译器非常高兴并且没有警告.如果您不打算修改被视为只读的相同地图,这可能会很危险,但表明您可以为效果进行转换.

如果你不想修改原始地图的机会,那么当然总是通过简单地用另一个Map调用HashMap的构造函数来制作副本HashMap(readOnlyMap).或者做一个扩展功能:

    fun <K, V> Map<K, V>.toMutableCopy() = HashMap(this)
Run Code Online (Sandbox Code Playgroud)

并称之为:

    val mutableMap = readOnlyMap.toMutableCopy()
Run Code Online (Sandbox Code Playgroud)

现在你有了简单的方法.

也可以看看:

  • 我建议反对`是MutableMap`检查,因为它可以为实际上不可变的Java集合返回`true`.例如,尝试`Collections.unmodifiableMap(mutableMapOf("a"到"b"))是MutableMap <*,*>`. (2认同)
  • 在某些情况下投射地图,而在其他情况下复制它可能会导致一些不可预测的行为。我不确定您的回答是否应该鼓励这样做。 (2认同)