8

我需要一个hashCodeJava 实现,它忽略我的类中字段的顺序Edge。Node first 可能是 Node second,第二个可能是 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

4

2 回答 2

10

您可以使用某种交换操作来代替现在的操作,例如加法:

@Override
public int hashCode() {
    int hash = 17;
    int hashMultiplikator = 79;
    int hashSum = first.hashCode() + second.hashCode();
    hash = hashMultiplikator * hash * hashSum;
    return hash;
}

我建议您仍然使用乘数,因为它为您的哈希码提供了一些熵。在这里查看我的答案,其中说:

散列需要遵循的一些好的规则是:

  • 混淆你的运营商。通过混合您的运算符,您可以使结果变化更大。在这个测试中简单地使用x * y,我有非常多的碰撞。
  • 使用素数进行乘法运算。素数具有有趣的二进制特性,导致乘法更加不稳定。
  • 避免使用移位运算符(除非您真的知道自己在做什么)。他们将大量的零或一插入数字的二进制文件中,从而降低其他操作的波动性,甚至可能减少您可能的输出数量。
于 2013-06-10T07:13:41.433 回答
2

要解决您的问题,您必须结合组件的两个 hashCode。

一个例子可能是:

@Override
public int hashCode() {
    int prime = 17;
    return prime * (first.hashCode() + second.hashCode());
}

请检查这是否符合您的要求。加法的乘法或异或也是可能的。

于 2013-06-10T06:57:07.470 回答