重写java.util.HashMap.get()方法

时间:2012-03-22 05:00:02

标签: scala

这个问题可能听起来很奇怪,但我感兴趣的是,如果可以在scala中覆盖java哈希映射的get()方法,那么: 如果值不在哈希映射中,而不是返回null,我们打印一些语句并调用另一个方法?

3 个答案:

答案 0 :(得分:3)

我强烈建议避免继承Java集合。即使在纯粹的OO语境中,GoF书籍也反对这种继承。但如果你真的想要它,你可以看看其他答案。

现在,在Scala上下文中,您有两个主要选项:

  1. 您将其转换为Scala地图,然后调用withDefault方法来执行您要查找的内容。有几种方法可以将收集转换为Java。

  2. 如果此选项不适合您,您可以考虑使用具有隐式视图的合成(又名 pimp-my-library 样式)。隐藏的观点现在可能过度使用,但它们允许丰富现有的类(你无法控制)而不会干扰继承。

  3. 如果您需要代码示例,请发表评论。

答案 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)

正如杰德和范式已经指出的那样,这种压倒一个大类的方法可能会有问题。例如,地图客户端代码可能期望containsget对应。

如果你坚持这样做,你可以将缺失值的打印和默认值的返回分成不同的特征。

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