我需要在Java中使用hashCode
实现,它忽略了我的类Edge
中字段的顺序。 Node首先可能是Node第二个,第二个可能是Node first。
这是我的方法取决于顺序:
public class Edge {
private Node first, second;
@Override
public int hashCode() {
int hash = 17;
int hashMultiplikator = 79;
hash = hashMultiplikator * hash
+ first.hashCode();
hash = hashMultiplikator * hash
+ second.hashCode();
return hash;
}
}
有没有办法计算一个哈希值,该哈希值适用于以下边缘相同但唯一的?
Node n1 = new Node("a");
Node n2 = new Node("b");
Edge ab = new Edge(n1,n2);
Edge ba = new Edge(n2,n1);
ab.hashCode() == ba.hashCode()
应为true
。
答案 0 :(得分:6)
您可以使用某种交换操作而不是现在的操作,例如添加:
@Override
public int hashCode() {
int hash = 17;
int hashMultiplikator = 79;
int hashSum = first.hashCode() + second.hashCode();
hash = hashMultiplikator * hash * hashSum;
return hash;
}
我建议你仍然使用乘法器,因为它为你的哈希码提供了一些熵。请参阅my answer here,其中包含:
哈希遵循的一些好规则是:
- 混淆您的运营商。通过混合运算符,可以使结果变化更大。在这个测试中简单地使用
x * y
,我有一个非常好的 大量的碰撞。- 使用素数进行乘法运算。素数具有有趣的二元属性,导致乘法变得更加不稳定。
- 避免使用移位操作符(除非你真的知道你在做什么)。他们将大量的零或一些插入到二进制文件中 数量,减少其他业务的波动性甚至可能 缩小可能的输出数量。
答案 1 :(得分:2)
要解决您的问题,您必须组合组件的两个hashCodes。
一个例子可能是:
@Override
public int hashCode() {
int prime = 17;
return prime * (first.hashCode() + second.hashCode());
}
请检查这是否符合您的要求。此外,还可以进行多次加法或XOR加法。