假设我有以下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')
个实例,当然是通过工厂调用。
答案 0 :(得分:1)
将A
和AWrapper
作为键放在同一张地图中听起来不对。但如果这是你想要的,你可以使用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; }
}