2012-04-12 33 views
3

通常,我发现自己实现了从输入源构建地图的方法。在这种情况下,我使用scala.collection.mutable.Map,假设更快的速度和效率;但是,一旦这个集合建立,我不再希望它是可变的。从本地构建的可变映射返回不可变映射的首选方式是什么?

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

感谢您的回复。

+0

我想在[这个其他问题]中使用'newBuilder'(http://stackoverflow.com/questions/26079146/scala-initializing-mutable-maps-and-exposing-them-as-immutable/26081768# 26081768),然后'.result'将是一个等价的解决方案,具有一些样式优点,定义了一个可变的Map [ – matanster 2014-09-28 17:13:24

回答

7

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

我认为将类型设置为scala.collection.Map确实会令人困惑。它也不会保护你免受设置类型的人的影响。制作immutable.Map型号清晰安全。

5

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

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

+0

]。在读完你和@ dhg的回答之后,我同意toMap是最好的解决方案。我认为'toMap'闻到了我,因为从现有的集合构建一个新的集合似乎是错误的,当时我只想隐藏可变的方法。 (我正在处理非常大的集合。)话虽如此,我确实忘记了客户端可能会将其重新转换为潜在的可变类型,这更糟糕。 类型安全解决方案ftw。 – pathdependent 2012-04-12 16:49:15

+0

@pathdependent - 如果速度很重要,您应该检查以确保构建可变映射的速度更快,然后将其添加到不可变映射中,而不仅仅是从头构建不可变映射。如果空间很重要,你一定希望从头开始构建不可变的地图,所以你不需要同时出现两个地图。 – 2012-04-12 18:01:28

0
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]] 

你可以施放newMapmutable.Map,但是这种修改会抛出UnsupportedOperationException

在我的情况下,地图可能足够小,以至于toMap可能会更快并且使用更少的内存。