2012-04-12 34 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可能會更快並且使用更少的內存。