如果我正在使用 Scala Multimap,并且我想获取与键关联的值或空集,我是否必须编写以下内容?
multimap.getOrElse("key", new collection.mutable.HashSet())
似乎以下内容应该可以工作。空集似乎是一个很好的默认值。
multimap.getOrElse("key")
Normally you would use Map.withDefaultValue
for this. However, it looks as if you can't really get this behavior and still have a collection typed as a MultiMap[A, B]
. The return type of MultiMap.withDefaultValue
is Map[A, Set[B]]
. So unfortunately you'll have to abandon the use of the MultiMap mixin to get the behavior you desire.
正如您所观察到的,该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
奇怪的是,如果 of 的类型是 abstract ,上述方法将不起作用collection.Map
。源代码中的注释说这是由于方差问题。
withDefaultValue
可用于此用例。例如:
import collection.mutable._
val multimap = Map[String, HashSet[String]]() withDefaultValue(new HashSet())
scala> multimap("key")
// res1: scala.collection.mutable.HashSet[String] = Set()
正如Garrett Rowe 指出的那样,由于在使用 mixin 时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)