这个问题可能听起来很奇怪,但我感兴趣的是,如果可以在scala中覆盖java哈希映射的get()方法,那么: 如果值不在哈希映射中,而不是返回null,我们打印一些语句并调用另一个方法?
答案 0 :(得分:3)
我强烈建议避免继承Java集合。即使在纯粹的OO语境中,GoF书籍也反对这种继承。但如果你真的想要它,你可以看看其他答案。
现在,在Scala上下文中,您有两个主要选项:
您将其转换为Scala地图,然后调用withDefault
方法来执行您要查找的内容。有几种方法可以将收集转换为Java。
如果此选项不适合您,您可以考虑使用具有隐式视图的合成(又名 pimp-my-library 样式)。隐藏的观点现在可能过度使用,但它们允许丰富现有的类(你无法控制)而不会干扰继承。
如果您需要代码示例,请发表评论。
答案 1 :(得分:2)
不确定;类和方法都没有标记为final
。在覆盖方法时,您只需使用AnyRef
而不是Object
。
scala> val x = new java.util.HashMap[String, String] {
| override def get(x: AnyRef): String = {
| super.get(x) match {
| case null => println("not found"); anotherMethod
| case v => v
| }
| }
|
| def anotherMethod = "default"
| }
x: java.util.HashMap[String,String] = {}
scala> x.get("foo")
not found
res3: String = default
答案 2 :(得分:2)
正如杰德和范式已经指出的那样,这种压倒一个大类的方法可能会有问题。例如,地图客户端代码可能期望contains
和get
对应。
如果你坚持这样做,你可以将缺失值的打印和默认值的返回分成不同的特征。
import java.util.{ Map, HashMap }
trait NotFoundPrinting[K, V] extends Map[K, V] {
abstract override def get(k: AnyRef): V = {
val v = super.get(k)
if (v == null) {
println("not found: " + k)
v
} else {
v
}
}
}
trait Default[K, V] extends Map[K, V] {
abstract override def get(k: AnyRef): V = {
val v = super.get(k)
if (v == null) default else v
}
def default: V
}
def test[A: Manifest](h: HashMap[String, Int]) {
h.put("existing", 1)
println("existing")
println(h.get("existing"))
println("missing")
println(h.get("missing"))
println()
}
test(new HashMap[String, Int] with NotFoundPrinting[String, Int])
test(new HashMap[String, Int] with Default[String, Int] {
val default = 42
})
test(new HashMap[String, Int] with NotFoundPrinting[String, Int] with Default[String, Int] {
val default = 42
})
// The next one is not useful, it would only print if default was null which is kind of pointless.
test(new HashMap[String, Int] with Default[String, Int] with NotFoundPrinting[String, Int] {
val default = 42
})
将打印
existing
1
missing
not found: missing
null
existing
1
missing
42
existing
1
missing
not found: missing
42
existing
1
missing
42