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

Scala 重写java.util.HashMap.get()方法,scala,Scala,这个问题听起来可能很奇怪,但我感兴趣的是,是否可以在scala中重写java哈希映射的get()方法,以便: 如果该值不在哈希映射中,我们将打印一些语句并调用另一个方法,而不是返回null?确定;类和方法均未标记为final。重写方法时,只需使用AnyRef而不是Object scala> val x = new java.util.HashMap[String, String] { | override def get(x: AnyRef): String = {

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

确定;类和方法均未标记为
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

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

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

  • 您可以将其转换为Scala映射,然后调用
    with default
    方法,该方法完成您要查找的内容。有几种将集合从Java转换为Java的方法

  • >P>如果这个选项不适合你,你可以考虑使用隐含视图的构图(ApaPiMin我的库样式)。隐式视图现在可能被过度使用,但它们允许在不影响继承的情况下丰富现有类(您无法控制)


    如果您需要代码示例,请留下注释。

    正如Jed和paradigmatic已经指出的那样,这种重写更大类的单个方法可能会有问题。例如,映射客户机代码可能期望
    包含
    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
    

    虽然这是可能的,但实际上这不是一个好主意,因为您违反了映射接口。最好将类封装到另一个不实现Map的对象中。