我认为可以按照以下方式完成
val hash = new HashMap[String, ListBuffer[Int]].withDefaultValue(ListBuffer())
hash("A").append(1)
hash("B").append(2)
println(hash("B").head)
然而,上面打印出不直观的值1.我想要
hash("B").append(2)
在幕后执行以下操作
if (!hash.contains("B")) hash.put("B", ListBuffer())
答案 0 :(得分:10)
使用getOrElseUpdate
在访问点提供默认值:
scala> import collection.mutable._
import collection.mutable._
scala> def defaultValue = ListBuffer[Int]()
defaultValue: scala.collection.mutable.ListBuffer[Int]
scala> val hash = new HashMap[String, ListBuffer[Int]]
hash: scala.collection.mutable.HashMap[String,scala.collection.mutable.ListBuffer[Int]] = Map()
scala> hash.getOrElseUpdate("A", defaultValue).append(1)
scala> hash.getOrElseUpdate("B", defaultValue).append(2)
scala> println(hash("B").head)
2
答案 1 :(得分:8)
withDefaultValue
每次都使用完全相同的值。在您的情况下,每个人都可以使用相同的空ListBuffer
。
如果您使用withDefault
,则每次都可以生成新的ListBuffer
,但不会存储。
所以你真正喜欢的是一种可以添加默认值的方法。您可以在包装类中创建这样的方法,然后编写隐式转换:
class InstantiateDefaults[A,B](h: collection.mutable.Map[A,B]) {
def retrieve(a: A) = h.getOrElseUpdate(a, h(a))
}
implicit def hash_can_instantiate[A,B](h: collection.mutable.Map[A,B]) = {
new InstantiateDefaults(h)
}
现在你的代码按照需要工作了(除了额外的方法名称,如果你愿意,可以选择更短的方法名称):
val hash = new collection.mutable.HashMap[
String, collection.mutable.ListBuffer[Int]
].withDefault(_ => collection.mutable.ListBuffer())
scala> hash.retrieve("A").append(1)
scala> hash.retrieve("B").append(2)
scala> hash("B").head
res28: Int = 2
请注意,解决方案(带隐式)根本不需要知道默认值本身,因此您可以执行此操作一次,然后默认添加内容。