【问题标题】:Copy Immutable Map to Mutable Map in Kotlin在 Kotlin 中将不可变映射复制到可变映射
【发布时间】:2016-07-26 15:38:41
【问题描述】:

如果我有一个 immutableMap: Map<String, Int> 并想将其转换为 mutableMap: MutableMap<String, Int>,那么最好的方法是什么?好像没有什么方便的方法。

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    更新: Kotlin 1.1 标准库有一个.toMutableMap() 函数。应该使用它而不是创建自己的。

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

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

    fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> {
      return HashMap(this)
    }
    

    其他一些答案建议检查地图是否为MutableMap,如果是则转换为它。应该不惜一切代价避免这种情况,因为这是一种不好的做法。在 Kotlin 中它被向下转换为 Map 的事实意味着不应更改此 Map,这样做会很危险。

    【讨论】:

      【解决方案2】:

      首先,正如之前关于 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()
      

      现在你有了简单的方法。

      另请参阅:

      【讨论】:

      • 我认为你应该明确指定 HashMap 的泛型,否则你最终会得到一个带有平台键/值类型的映射。
      • 我建议不要使用 is MutableMap 检查,因为它可以为实际上不可变的 Java 集合返回 true。例如尝试Collections.unmodifiableMap(mutableMapOf("a" to "b")) is MutableMap&lt;*,*&gt;
      • 这对我来说似乎是最好的答案。您可以添加的一件事是不直接使用HashMap 的示例(我相信mutableMapOf 实际上使用LinkedHashMap)。例如:val mutableMap = map.entries.associateTo(mutableMapOf()) { entry -&gt; entry.toPair() }.
      • 在某些情况下投射地图,而在其他情况下复制地图可能会导致一些不可预知的行为。我不确定你的回答是否应该鼓励。
      • 很大程度上取决于他未知的完整用例,所以我提供了各种选择。买家小心。
      猜你喜欢
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2020-10-14
      相关资源
      最近更新 更多