Scala:使用具有默认值的 HashMap
Posted
技术标签:
【中文标题】Scala:使用具有默认值的 HashMap【英文标题】:Scala: Using HashMap with a default value 【发布时间】:2011-04-08 14:40:45 【问题描述】:我有一个可变的 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, "_"))
有什么方法可以创建一个 HashMap(或类似的类),以便尝试访问未定义的键返回一个在创建 HashMap 时设置的默认值?我注意到 HashMap.default 只是设置为抛出异常,但我想知道这是否可以更改...
【问题讨论】:
对于任何偶然发现这个问题的人,missingfaktor 的帖子正确地指出“Scala 2.9.1. mutable.Map 带有 withDefaultValue 方法” 【参考方案1】:哇,在我在这里发布我的最后一个答案一年后,我碰巧访问了这个帖子。 :-)
Scala 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 = ""
【讨论】:
我担心这个性能 - mutable.Map 使用 HashMaps 吗?它的表现如何?WithDefault
仅覆盖default
方法(因此仅影响apply
)并在未找到密钥时返回默认值。其他所有内容都发送到底层Map
【参考方案2】:
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 = -
编辑:
对于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 = -
可能有更好的方法来做到这一点。等待其他人回应。
【讨论】:
@PythonPower:您没有在原始问题中指定使用mutable.HashMap
。我不知道如何使用mutable.HashMap
。我得研究一下 API。
是的,对不起,我没有具体说明——我已经编辑了我的问题,以便现在清楚。【参考方案3】:
试试这个:
import collection.mutable.HashMap
val x = new HashMap[Int,String]() override def default(key:Int) = "-"
x += (1 -> "b", 2 -> "a", 3 -> "c")
然后:
scala> x(1)
res7: String = b
scala> x(2)
res8: String = a
scala> x(3)
res9: String = c
scala> x(4)
res10: String = -
【讨论】:
+1。想知道为什么mutable.HashMap
不提供像 immutable.HashMap
这样的 withDefaultValue
方法。
这是一种可怕的语法,但它确实有效。也许应该将可变 HashMap 缺少 withDefaultValue 报告为错误?
有一个“!!! todo: 移动到通用地图?”在scala-lang.org/api/current/scala/collection/immutable/Map.html 中的相邻withDefault
中发表评论。因此,这可能并不过分。 scala-user 邮件列表可能是查询此问题并查看是否应报告错误的好地方。
@PythonPower 已提交增强票证lampsvn.epfl.ch/trac/scala/ticket/3829。
感谢您的报告!很高兴看到 Scala 得到如此积极的改进。【参考方案4】:
我更像是一个 java 人...但是如果 getOrElse
不是最终的,你为什么不扩展 HasMap
并提供这样的东西:
override def getOrElse(k: Int, default: String) =
return super.getOrElse(k,"_")
注意:语法可能搞砸了,但希望你能明白这一点
【讨论】:
是的,我认为可以扩展HashMap。在这种情况下,更改 HashMap.default 方法以返回我想要的可能会更容易。构造函数可以采用默认值,而 HashMap.default 方法只会返回该值。不过,我希望有一种更简单的方法。 我们不这样做是因为它比getOrElse
更复杂 - 它的灵活性较低,不必要地冗长,如果你必须这样做,那么它是一个强大的表明你应该使用一些高级抽象,比如 monoids。以上是关于Scala:使用具有默认值的 HashMap的主要内容,如果未能解决你的问题,请参考以下文章
在 pyspark 的 Scala UDF 中使用默认参数值?