Java 哈希代码比较问题
我有一个对象列表,在我们的例子中称为rule,这个对象本身是一个字段列表,我必须对其进行hashcode比较,因为我们不能在 系统 i、 假设我有两条规则R1和R2以及字段A和B 现在,如果R1中A和B的值分别为7和2 在R2中,分别是3和4,然后是我用来检查重复性的过程 对系统中的规则进行哈希代码比较失败 我使用的方法是Java 哈希代码比较问题,java,hashcode,Java,Hashcode,我有一个对象列表,在我们的例子中称为rule,这个对象本身是一个字段列表,我必须对其进行hashcode比较,因为我们不能在 系统 i、 假设我有两条规则R1和R2以及字段A和B 现在,如果R1中A和B的值分别为7和2 在R2中,分别是3和4,然后是我用来检查重复性的过程 对系统中的规则进行哈希代码比较失败 我使用的方法是 for(Rule rule : rules){ changeableAttrCode=0; fieldCounter=1; attributes = rule.getAt
for(Rule rule : rules){
changeableAttrCode=0;
fieldCounter=1;
attributes = rule.getAttributes();
for(RuleField ruleField : attributes){
changeableAttrCode = changeableAttrCode + (fieldCounter * ruleField.getValue().hashCode());
fieldCounter++;
}
parameters = rule.getParameters();
for(RuleField ruleField : parameters){
changeableAttrCode = changeableAttrCode + (fieldCounter * ruleField.getValue().hashCode());
fieldCounter++;
}
changeableAttrCodes.add(changeableAttrCode);
这里是changeableAttrCodes,我们存储所有规则的hashcode
所以,请给我建议更好的方法,这样将来就不会出现这种问题,同时也可以看到系统中规则的双重性
提前感谢更新了您的哈希算法没有产生良好的哈希值分布-它为(7,2)和(3,4)提供了相同的值: 对于(11,0),(-1,6)。。。根据当前的算法,我们可以轻松地组成无数个类似的等价类 当然,您不能避免冲突-如果您有足够的实例,哈希冲突是不可避免的。但是,您应该将碰撞的机会降至最低。好的散列算法力求将散列值均匀地分布在广泛的值上。实现这一点的典型方法是为包含n个独立字段的对象生成散列值,该散列值是一个n位数字,其基数足以容纳各个字段的不同散列值 在您的情况下,不应与
字段计数器相乘,而应与素数常量相乘,例如31(这将是您的数字的基数)。并将另一个素数常量添加到结果中,例如17。这样可以更好地分散散列值。(当然,具体基础取决于您的字段可以采用什么样的值-我没有这方面的信息。)
另外,如果您实现了hashCode
,强烈建议您也实现equals
——事实上,您应该使用后者来测试相等性
这里有一篇文章是关于。更新的您的哈希算法没有产生良好的哈希值分布-它为(7,2)和(3,4)提供了相同的值:
对于(11,0),(-1,6)。。。根据当前的算法,我们可以轻松地组成无数个类似的等价类
当然,您不能避免冲突-如果您有足够的实例,哈希冲突是不可避免的。但是,您应该将碰撞的机会降至最低。好的散列算法力求将散列值均匀地分布在广泛的值上。实现这一点的典型方法是为包含n个独立字段的对象生成散列值,该散列值是一个n位数字,其基数足以容纳各个字段的不同散列值
在您的情况下,不应与字段计数器相乘,而应与素数常量相乘,例如31(这将是您的数字的基数)。并将另一个素数常量添加到结果中,例如17。这样可以更好地分散散列值。(当然,具体基础取决于您的字段可以采用什么样的值-我没有这方面的信息。)
另外,如果您实现了hashCode
,强烈建议您也实现equals
——事实上,您应该使用后者来测试相等性
这是一篇关于的文章。我不明白你在这里想做什么。对于大多数散列函数场景,冲突是不可避免的,因为要散列的对象远远多于可能的散列值(这是一个鸽子洞原则)
通常情况下,两个不同的对象可能具有相同的哈希值。不能仅依靠哈希函数来消除重复项
一些散列函数在最小化冲突方面比其他函数更好,但这仍然是不可避免的
也就是说,有一些简单的指导原则通常可以提供足够好的哈希函数。Joshua Bloch在其《有效Java第二版》一书中给出了以下内容:
- 在名为
result
的int
变量中存储一些常量非零值,例如17
- 为每个字段计算一个
int
hashcodec
:
- 如果字段是布尔值,则计算
(f?1:0)
- 如果字段是一个
字节、字符、短字符、int
,则计算(int)f
- 如果字段是长的,则计算
(int)(f^(f>>32))
- 如果字段是一个
float
,则计算float.floatToIntBits(f)
- 如果该字段是一个
double
,请计算double.double到longbits(f)
,然后像上面一样对结果的long
进行散列
- 如果字段是对象引用,并且此类的
equals
方法通过递归调用equals
来比较字段,则递归调用字段上的hashCode
。如果该字段的值为null
,则返回0
- 如果字段是数组,则将其视为每个元素都是单独的字段。如果数组字段中的每个元素都是重要的,则可以使用1.5版中添加的
数组.hashCode
方法之一
- 将hashcode
c
组合成result
,如下所示:result=31*result+c代码>
我不明白你在这里想干什么。对于大多数散列函数场景,冲突是不可避免的,因为要散列的对象远远多于可能的散列值(这是一个鸽子洞原则)
通常情况下,两个不同的对象可能具有相同的哈希值。不能仅依靠哈希函数来消除重复项
一些散列函数
1 * 7 + 2 * 2 = 11
1 * 3 + 2 * 4 = 11