您的问题有点不清楚,您需要/哪些字段足以唯一区分密钥。
通常,您应该通过乘以素数来组合单个散列(在复合键中)。
假设第一个例子:
public int hashCode() {
int h = className.hashCode() * 23;
h += methodName.hashCode() * 17;
h += uniqueNumber;
return h;
}
OTOH 如果uniqueNumber
实际上是独一无二的,您可以简化:
public int hashCode() {return uniqueNumber;}
在您的评论中,您提到了一件事:“仅使用 uniqueNumber 将生成唯一的哈希值,但我将失去在哈希图中引用特定值的能力”。
现在这非常重要:“实例身份”是一个非常不同的哈希和查找的东西,与“价值”!您不能对两者使用相同的哈希码和映射。
例如,如果您需要一个 Key(ClassName, MethodName) -> SomeValue 查找,这将是一个“值”查找,并且需要通过 ClassName 和 MethodName 值进行散列,以便可以重复:即,您可以构造一个Map.get() 执行查找的键。
“Instance Identity”实际上已经内置了对 Java 中的散列和映射的支持——它被称为 IdentityHashMap。
但是对于大多数情况,包括可能用于映射的复合键,尤其是复合键,需要能够重新构造键以稍后执行查找。所以键应该有值语义,你uniqueNumber
是否真的应该是键的一部分是值得怀疑的。
当您稍后进行查找时,如何获得正确uniqueNumber
的检索数据?我的感觉是:
要么应该有一个一流的实体,您可以直接将其用作键(因此不再需要 CompositeKey 类),或者
你不能重复地得到uniqueNumber
,在这种情况下它不起作用/无论如何都不需要。
总结一下:如果uniqueNumber
真的需要或完全适用,我希望它已经被封装在一个一流的实体中。事实并非如此。看起来您很可能应该使用基于值的 key,并删除 uniqueNumber 位(至少从这里开始)。
所以我的建议:
public int hashCode() {
int h = className.hashCode() * 23;
h += methodName.hashCode() * 17;
h += desc.hashCode();
return h;
}
让我知道这是否有帮助。