具有两个没有顺序的字段的唯一hashCode

时间:2013-06-10 06:43:34

标签: java hashcode

我需要在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

2 个答案:

答案 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加法。