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

Luk*_*asz 43 scala scala-collections

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

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

提前致谢.

Ily*_*kov 102

为什么不使用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()
Run Code Online (Sandbox Code Playgroud)


oxb*_*kes 22

apply您可以随时使用get,而不是使用访问地图,返回Option[V]然后getOrElse:

map.get(k) getOrElse Nil
Run Code Online (Sandbox Code Playgroud)

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

~map.get(k)
Run Code Online (Sandbox Code Playgroud)

这是极为有用的,因为相同的语法工程时(例如)你的价值观是Int,Double等(任何事情上有一个Zero类型类).


scala邮件列表中有关于使用的争论很多,Map.withDefault因为这对于该isDefinedAt方法的表现如何.由于这个原因,我倾向于避开它.


kas*_*ens 11

有一个方法withDefaultValueMap:

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()
Run Code Online (Sandbox Code Playgroud)

  • 并且还有一个`withDefault`,它具有一个功能. (9认同)