Unique hashCode with two fields without order

孤街浪徒 提交于 2020-02-13 05:20:21

问题


I need a hashCode implementation in Java which ignores the order of the fields in my class Edge. It should be possible that Node first could be Node second, and second could be Node first.

Here is my method is depend on the order:

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;
    }
}

Is there a way to compute a hash which is for the following Edges the same but unique?

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() should be true.


回答1:


You can use some sort of commutative operation instead of what you have now, like addition:

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

I'd recommend that you still use the multiplier since it provides some entropy to your hash code. See my answer here, which says:

Some good rules to follow for hashing are:

  • Mix up your operators. By mixing your operators, you can cause the results to vary more. Using simply x * y in this test, I had a very large number of collisions.
  • Use prime numbers for multiplication. Prime numbers have interesting binary properties that cause multiplication to be more volatile.
  • Avoid using shift operators (unless you really know what you're doing). They insert lots of zeroes or ones into the binary of the number, decreasing volatility of other operations and potentially even shrinking your possible number of outputs.



回答2:


To solve you problem you have to combine both hashCodes of the components.

An example could be:

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

Please check if this matches your requirements. Also a multiplikation or an XOR insted of an addition could be possible.



来源:https://stackoverflow.com/questions/17018192/unique-hashcode-with-two-fields-without-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!