什么是整数元组的好哈希函数?

时间:2011-06-06 00:25:19

标签: java hashcode integer-hashing

我有这门课......

public class StartStopTouple {

    public int iStart;
    public int iStop;
    public int iHashCode;

    public StartStopTouple(String start, String stop) {
        this.iStart = Integer.parseInt(start);
        this.iStop = Integer.parseInt(stop);
    }

    @Override
    public boolean equals(Object theObject) {

        // check if 'theObject' is null
        if (theObject == null) {
            return false;
        }
        // check if 'theObject' is a reference to 'this' StartStopTouple... essentially they are the same Object
        if (this == theObject) {
            return true;
        }

        // check if 'theObject' is of the correct type as 'this' StartStopTouple
        if (!(theObject instanceof StartStopTouple)) {
            return false;
        }

        // cast 'theObject' to the correct type: StartStopTouple
        StartStopTouple theSST = (StartStopTouple) theObject;

        // check if the (start,stop) pairs match, then the 'theObject' is equal to 'this' Object
        if (this.iStart == theSST.iStart && this.iStop == theSST.iStop) {
            return true;
        } else {
            return false;
        }
    } // equal() end

    @Override
    public int hashCode() {
        return iHashCode;
    }
}

...只有当一个Object中的iStartiStop等于iStart时,我才定义这些对象之间的相等性,而另一个对象中则iStop

因为我已经覆盖了equals(),我需要覆盖hashCode(),但我不确定如何为这个类定义一个好的哈希函数。使用iStartiStop为此类创建哈希码的好方法是什么?

3 个答案:

答案 0 :(得分:2)

来自Bloch的“Effective Java”:

int iHashCode = 17;
iHashCode = 31 * iHashCode + iStart;
iHashCode = 31 * iHashCode + iStop;

注意:选择31是因为乘以31可以由VM优化为位操作。 (但是在你的情况下,性能没有用,因为@Ted Hopp提到你只计算一次值。)

注意:如果iHashCode翻过最大的int,则无关紧要。

答案 1 :(得分:2)

我很想使用它,特别是因为你要记住它:

Long.valueOf((((long) iStart) << 32) | istop)).hashcode();

答案 2 :(得分:2)

最简单的可能是最好的

iHashCode = iStart^iStop;

两个值的XOR

请注意,当交换启动和停止时,这将给出相同的哈希码

作为另一种可能性你可以做到

iHashCode = ((iStart<<16)|(iStart>>>16))^iStop;

这第一个桶移位开始16然后xors停止,因此最低有效位在xor中分开(如果开始从不大于65k(更准确地说是2 ^ 16),则可以省略{{1部分)