Scala:使用具有默认值的 HashMap

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3648870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:24:29  来源:igfitidea点击:

Scala: Using HashMap with a default value

oopdata-structuresscalahashmap

提问by huynhjl

I have a mutable HashMap and would like to use it like a default-dictionary. The obvious method appears to be to use getOrElse and provide the default value each time as a second value. However this seems a little inelegant in my use case since the default value doesn't change.

我有一个可变的 HashMap 并且想像默认字典一样使用它。显而易见的方法似乎是使用 getOrElse 并每次提供默认值作为第二个值。然而,这在我的用例中似乎有点不雅,因为默认值不会改变。

var x = HashMap(1 -> "b", 2 -> "a", 3 -> "c")

println(x.getOrElse(4, "_")
println(x.getOrElse(5, "_"))
// And so on...
println(x.getOrElse(10, "_"))

Is there any way to create a HashMap (or similar class) such that attempting to access undefined keys returns a default value set on the creation of the HashMap? I notice that HashMap.default is just set to throw an exception but I wonder if this can be changed...

有什么方法可以创建 HashMap(或类似的类),以便尝试访问未定义的键会返回在创建 HashMap 时设置的默认值?我注意到 HashMap.default 只是设置为抛出异常,但我想知道是否可以更改...

回答by missingfaktor

Wow, I happened to visit this thread exactly one year after I posted my last answer here. :-)

哇,在我在这里发布最后一个答案的整整一年后,我碰巧访问了这个线程。:-)

Scala 2.9.1. mutable.Mapcomes with a withDefaultValuemethod. REPL session:

斯卡拉 2.9.1。mutable.Map自带withDefaultValue方法。REPL 会话:

scala> import collection.mutable
import collection.mutable

scala> mutable.Map[Int, String]().withDefaultValue("")
res18: scala.collection.mutable.Map[Int,String] = Map()

scala> res18(3)
res19: String = ""

回答by huynhjl

Try this:

试试这个:

import collection.mutable.HashMap
val x = new HashMap[Int,String]()  { override def default(key:Int) = "-" }
x += (1 -> "b", 2 -> "a", 3 -> "c")

Then:

然后:

scala> x(1)
res7: String = b

scala> x(2)
res8: String = a

scala> x(3)
res9: String = c

scala> x(4)
res10: String = -

回答by missingfaktor

scala> val x = HashMap(1 -> "b", 2 -> "a", 3 -> "c").withDefaultValue("-")
x: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,b), (2,a), (3,c))

scala> x(3)
res0: java.lang.String = c

scala> x(5)
res1: java.lang.String = -

EDIT:

编辑:

For mutable.HashMap, you could do the following:

对于mutable.HashMap,您可以执行以下操作:

scala> import collection.mutable
import collection.mutable

scala> val x = new mutable.HashMap[Int, String] {
     |   override def apply(key: Int) = super.get(key) getOrElse "-"
     | }
x: scala.collection.mutable.HashMap[Int,String] = Map()

scala> x += (1 -> "a", 2 -> "b", 3 -> "c")
res9: x.type = Map((2,b), (1,a), (3,c))

scala> x(2)
res10: String = b

scala> x(4)
res11: String = -

There might be a better way to do this. Wait for others to respond.

可能有更好的方法来做到这一点。等待其他人回应。

回答by Pablo Fernandez

I'm more a java guy... but if getOrElseis not final, why don't you just extend HasMapand provide something like this:

我更像是一个 Java 人......但如果getOrElse不是最终的,你为什么不扩展HasMap并提供这样的东西:

override def getOrElse(k: Int, default: String) = {
  return super.getOrElse(k,"_")
}

Note: syntax is probably screwed up but hopefully you'll get the point

注意:语法可能搞砸了,但希望你能明白这一点