gpt4 book ai didi

java - 制作哈希函数的最佳方法

转载 作者:行者123 更新时间:2023-12-02 06:31:25 24 4
gpt4 key购买 nike

我正在 Java 中为 HashMap 构建复合键,并希望为每个对象确定我自己的哈希代码。我的问题是以下两种方法中最好的方法是什么。我的复合键有 3 个 String 属性和 1 个 int 属性。

public int hashCode(){
return (className + methodName + uniqueNumber).hashCode();
}

public int hashCode(){
return (className + methodName + desc + uniqueNumber).hashCode();
}

我必须有类名、方法名和唯一编号,以保证每个键都有唯一的哈希码。我想采用碰撞可能性最小的方法。我的直觉是,我“添加”到 HashMap 函数的属性越多,发生冲突的可能性就越小。但是,我并不完全确定这是正确的。

最佳答案

您的问题有点不清楚,您需要/足以唯一区分 key 的字段。

通常,您应该通过乘以质因数来组合各个哈希值(在复合键内)。

假设第一个例子:

public int hashCode() {
int h = className.hashCode() * 23;
h += methodName.hashCode() * 17;
h += uniqueNumber;
return h;
}

OTOH 如果 uniqueNumber 实际上是唯一的,您可以简化:

public int hashCode() {return uniqueNumber;}

在您的评论中提到一件事:“仅使用 uniqueNumber 将生成唯一的哈希值,但我将失去在 HashMap 中引用特定值的能力”。

现在这一点非常重要:“实例身份”与“值”进行散列和查找是非常不同的!您不能对两者使用相同的哈希码和映射。

例如,如果您需要一个 Key( ClassName, MethodName) -> SomeValue 查找,这将是一个“值”查找,并且需要按 ClassName 和 MethodName 值进行哈希处理,以便可以重复:即,所以您可以为 Map.get() 构造一个键来执行查找。

“Instance Identity”实际上内置了对 Java 中的哈希和映射的支持——它称为 IdentityHashMap。

但在大多数情况下,尤其是可能用于映射的复合键,需要能够重新构造该键以便稍后执行查找。因此键应该具有值语义,并且您的uniqueNumber是否实际上应该是键的一部分是值得怀疑的。

当你稍后去查找时,如何获得正确的uniqueNumber来检索数据?我的感受是:

  1. 要么应该有一个一流的实体,您可以直接将其用作键(因此不再需要 CompositeKey 类),要么

  2. 您无法重复获取uniqueNumber,在这种情况下它不起作用/无论如何都不需要。

总结一下:如果 uniqueNumber 确实需要或适用,我希望它已经封装在一流的实体中。事实并非如此。看起来您很可能应该使用基于值的键,并删除 uniqueNumber 位(至少从这里开始)。

所以我的建议:

public int hashCode() {
int h = className.hashCode() * 23;
h += methodName.hashCode() * 17;
h += desc.hashCode();
return h;
}

请告诉我这是否有帮助。

关于java - 制作哈希函数的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20025765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com