如何在Java中为包装器对象实现高效的哈希码?

时间:2015-12-07 18:49:32

标签: java wrapper hashcode composite

假设我有以下A类实现了接口M:

class A implements M {
   int i;

   int hashCode() { return i; }
}

A的包装器,例如

class AWrapper implements M {

    A a;

    public Wrapper(A a) {
       this.a = a;
    }

    int hashCode() { ??? }
}

此层次结构是一种复合模式。我的问题是什么是AWrapper类的好哈希码?我可以使用a.hashCode(),然后使用所有的A和 AWrapper将具有相同的哈希码。实现这种哈希码的最佳方法是什么?

有些人问这个设计背后的理由是什么,让我更具体一点。我正在为正则表达式编写数据类型。所以A是一个符号,有常规运算符,如*,+ ,?这基本上是符号的包装,例如Star(A)。我还想确保只有一个对象的实例,这就是我需要共享的原因,所以如果有人写道:

r1 = a*a
r2 = a*c

Seq(Star('a'), 'a')Seq(Star('a'), 'c')代表,我希望共享两个Star('a')个实例,当然是通过工厂调用。

1 个答案:

答案 0 :(得分:1)

AAWrapper作为键放在同一张地图中听起来不对。但如果这是你想要的,你可以使用Objects.hash(a)

  

当提供单个对象引用时,返回的值不等于该对象引用的哈希码。

作为旁注,如果AWrapper是不可变的并且经常调用hashCode方法并且A :: hashCode不是微不足道的并且内存占用不是问题,那么您可能想要预先计算哈希码(值得测试,如果在您的场景中值得):

class AWrapper implements M {

    private final A a;
    private final int hash;

    public Wrapper(A a) {
       this.a = a;
       hash = Objects.hash(a);
    }

    int hashCode() { return hash; }
}