4

如果我正在使用 Scala Multimap,并且我想获取与键关联的值或空集,我是否必须编写以下内容?

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

似乎以下内容应该可以工作。空集似乎是一个很好的默认值。

multimap.getOrElse("key")
4

4 回答 4

4

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.

于 2011-08-05T19:23:47.133 回答
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奇怪的是,如果 of 的类型是 abstract ,上述方法将不起作用collection.Map。源代码中的注释说这是由于方差问题。

于 2011-08-05T19:12:21.617 回答
0

withDefaultValue可用于此用例。例如:

import collection.mutable._
val multimap = Map[String, HashSet[String]]() withDefaultValue(new HashSet())
scala> multimap("key")
// res1: scala.collection.mutable.HashSet[String] = Set()
于 2011-08-05T19:15:58.520 回答
0

正如Garrett Rowe 指出的那样,由于在使用 mixin 时withDefaultValue没有保留正确的类型,因此您可以改写匿名类中的方法并保留以下行为:MultiMapdefaultMultiMap

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)
于 2016-05-02T21:22:57.810 回答