2011-08-05 79 views
4

如果我使用Scala的Multimap之,我想用鑰匙或者空集關聯的值,我必須寫下面?斯卡拉多重映射:獲得項目或其他空集​​

multimap.getOrElse("key", new collection.mutable.HashSet()) 

看來以下應該只是工作。空集似乎是一個很好的默認值。

multimap.getOrElse("key") 

回答

3

當你觀察到的,MultiMap特質不會做你想要的。但是,如果Map特別可變或不可變,則可以自己添加默認值。下面是一個例子,

scala> val m = collection.mutable.Map(1 -> 2) 
m: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2) 

scala> val m2 = m.withDefaultValue(42) 
m2: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2) 

scala> m2(1) 
res0: Int = 2 

scala> m2(2) 
res1: Int = 42 

奇怪的是,上面不會有如果m的類型是一個抽象collection.Map工作。源代碼中的評論說這是由於差異問題。

+0

嗯。 ..如果getOrElse(key)被添加,那將會很棒! – schmmd

0

withDefaultValue可用於此用例。例如:

import collection.mutable._ 
val multimap = Map[String, HashSet[String]]() withDefaultValue(new HashSet()) 
scala> multimap("key") 
// res1: scala.collection.mutable.HashSet[String] = Set() 
+0

這似乎沒有按預期工作。 'multimap(「key」)+ =「value」'不修改地圖。我猜默認值不會被緩存。 –

4

通常你會使用Map.withDefaultValue這一點。然而,看起來好像你不能真正得到這種行爲,仍然有一個類型爲MultiMap[A, B]的集合。 MultiMap.withDefaultValue的退貨類型爲Map[A, Set[B]]。所以不幸的是,你必須放棄使用MultiMap mixin來獲得你想要的行爲。

0

因爲如Garrett Rowenoted,使用混入時withDefaultValue不會保留正確的MultiMap類型,可以代替覆蓋一個匿名類的default方法和保存的MultiMap行爲:

scala> import collection.mutable.{ HashMap, MultiMap, Set } 
import collection.mutable.{HashMap, MultiMap, Set} 

scala> val map: MultiMap[String, Int] = new HashMap[String, Set[Int]] with MultiMap[String, Int] { 
    | override def default(key: String): Set[Int] = Set.empty[Int] 
    | } 
map: scala.collection.mutable.MultiMap[String,Int] = Map() 

scala> map("foo") 
res0: scala.collection.mutable.Set[Int] = Set() 

scala> map.addBinding("foo", 1) 
res1: map.type = Map(foo -> Set(1)) 

scala> map("foo") 
res2: scala.collection.mutable.Set[Int] = Set(1)