【问题标题】:What is the preferred way of returning an immutable map from a locally built mutable one?从本地构建的可变地图返回不可变地图的首选方式是什么?
【发布时间】:2015-08-22 13:44:13
【问题描述】:

我发现自己经常实现从输入源构建地图的方法。在这种情况下,我使用scala.collection.mutable.Map,假设速度和效率更高;但是,一旦构建了这个集合,我就不再希望它是可变的。

从可变映射返回不可变映射的首选 Scala 方式是什么?通常,我会做一个myMap.toMap,这显然有效,但有异味。或者,您可以将返回类型设置为 scala.collection.Map,这不需要构建新集合,但似乎会混淆读者。

感谢您的任何回复。

【问题讨论】:

  • 我认为在 this other question 中使用 newBuilder 然后 .result 将是一个等效的解决方案,与定义可变的 Map 相比具有一些风格优点

标签: scala scala-collections


【解决方案1】:

最好的方法是致电.toMap。它简短、干净,是一种明确的方式,表示您要将收藏转换为 immutable.Map

我认为将类型设置为scala.collection.Map 确实会令人困惑。它也不会保护您免受将类型设置回来的人的伤害。使类型immutable.Map 清晰且安全。

【讨论】:

    【解决方案2】:

    我不确定你为什么认为.toMap 有异味,但如果你想明确一点,collection.immutable.Map() ++ myMap 应该清楚地记录发生了什么。 (不要忘记();它们不是可选的。)

    仅仅改变返回类型并不能完全解决不变性问题;变异方法不再可见,但用户可以轻松地回退。不过,这是性能最高的方法,因为并没有真正改变。

    【讨论】:

    • 在阅读了您和@dhg 的回复后,我同意 toMap 是最好的解决方案。我认为toMap 对我来说很臭,因为当我只想隐藏可变方法时,从现有集合构建新集合似乎是错误的。 (我正在处理非常大的集合。)话虽如此,我确实忘记了客户端可以将其转换回底层可变类型,这更糟。类型安全的解决方案。
    • @pathdependent - 如果速度很重要,您应该检查以确保构建可变映射然后将其添加到不可变映射比从头开始构建不可变映射更快。如果空间很重要,您肯定希望从头开始构建不可变地图,这样您就不需要同时存在两个地图。
    【解决方案3】:
    import scala.collection._
    import scala.collection.JavaConversions._
    
    val myMap: mutable.Map[K,V] = ???
    val unmodifiable: mutable.Map[K,V] =
      java.util.Collections.unmodifiableMap[K,V](myMap)
    val newMap = unmodifiable.asInstanceOf[scala.collection.Map[K,V]]
    

    您可以将newMap 转换为mutable.Map,但修改会抛出UnsupportedOperationException

    在我的情况下,映射可能足够小,toMap 可能会更快并使用更少的内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-14
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      相关资源
      最近更新 更多