如何在Scala中使用默认操作实现Map

时间:2011-04-29 09:39:46

标签: scala scala-collections

class DefaultListMap[A, B <: List[B]] extends HashMap[A, B] {
    override def default(key: A) = List[B]() 
  }

我不想创建地图A -> List[B]。在我的情况下它是Long -> List[String]但是当我从地图获得没有值的密钥时,我想创建空的List而不是Exception被抛出。我尝试了不同的组合,但我不知道如何使代码通过编译器。

提前致谢。

5 个答案:

答案 0 :(得分:95)

为什么不使用withDefaultValue(value)?

scala> val m = Map[Int, List[String]]().withDefaultValue(List())
m: scala.collection.immutable.Map[Int,List[String]] = Map()

scala> m(123)
res1: List[String] = List()

答案 1 :(得分:22)

您可以随时使用apply,而不是使用get来访问地图,而Option[V]会返回getOrElse,然后再返回map.get(k) getOrElse Nil

~

scalaz 函数式编程库的一个重要特性是一元运算符List,这意味着“或零”,只要值类型有一个“零”定义(Nil做,当然零是~map.get(k) 。那么代码就变成了:

Int

这非常有用,因为相同的语法适用于(例如)您的值为DoubleZero等(任何有Map.withDefault类型类的东西)。


关于使用isDefinedAt的scala邮件列表存在很多争论,因为这对于{{1}}方法的行为如何。由于这个原因,我倾向于避开它。

答案 2 :(得分:10)

withDefaultValue上有Map方法:

scala> val myMap = Map(1 -> List(10), 2 -> List(20, 200)).withDefaultValue(Nil)
myMap: scala.collection.immutable.Map[Int,List[Int]] = Map((1,List(10)), (2,List(20, 200)))

scala> myMap(2)
res0: List[Int] = List(20, 200)

scala> myMap(3)
res1: List[Int] = List()

答案 3 :(得分:3)

为什么要在已有方法的情况下操作地图?

val m = Map(1L->List("a","b"), 3L->List("x","y","z"))  
println(m.getOrElse(1L, List("c"))) //--> List(a, b)
println(m.getOrElse(2L, List("y"))) //--> List(y)

答案 4 :(得分:2)

withDefault 也可以使用。

/** The same map with a given default function.
 *  Note: `get`, `contains`, `iterator`, `keys`, etc are not affected
 *  by `withDefault`.
 *
 *  Invoking transformer methods (e.g. `map`) will not preserve the default value.
 *
 *  @param d     the function mapping keys to values, used for non-present keys
 *  @return      a wrapper of the map with a default value
 */
 def withDefault[B1 >: B](d: A => B1): immutable.Map[A, B1]

示例:

scala> def intToString(i: Int) = s"Integer $i"
intToString: (i: Int)String

scala> val x = Map[Int, String]().withDefault(intToString)
x: scala.collection.immutable.Map[Int,String] = Map()

scala> x(1)
res5: String = Integer 1

scala> x(2)
res6: String = Integer 2

希望这有帮助。