将Java哈希代码组合成一个;大师;哈希码

将Java哈希代码组合成一个;大师;哈希码,java,hash,Java,Hash,我有一个实现了hashCode()的向量类。它不是我写的,而是用2个素数乘以2个向量分量,然后进行异或运算。这是: /*class Vector2f*/ ... public int hashCode() { return 997 * ((int)x) ^ 991 * ((int)y); //large primes! } …由于这是一个已建立的Java库,我知道它工作得很好 然后我有一个边界类,它包含两个向量,“开始”和“结束”(表示直线的端

我有一个实现了hashCode()的向量类。它不是我写的,而是用2个素数乘以2个向量分量,然后进行异或运算。这是:

    /*class Vector2f*/
...
    public int hashCode()
    {
        return 997 * ((int)x) ^ 991 * ((int)y); //large primes! 
    }
…由于这是一个已建立的Java库,我知道它工作得很好

然后我有一个边界类,它包含两个向量,“开始”和“结束”(表示直线的端点)。这两个向量的值是边界的特征

    /*class Boundary*/
...
    public int hashCode()
    {
        return 1013 * (start.hashCode()) ^ 1009 * (end.hashCode());
    }
在这里,我试图为构成此边界的唯一向量2元组(开始和结束)创建一个好的hashCode()。我的问题是:这个hashCode()实现能正常工作吗


(请注意,我在后一个hashCode()实现中使用了两个不同的素数;我不知道这是否必要,但我想,在试图避免公共因素时,最好是安全的,因为我认为这就是素数在哈希函数中流行的原因。)

这是正常的做法。我觉得这很合理。如果您使用的是Eclipse,您应该发现它可以为您生成
equals
hashCode
,只需查看源代码菜单即可。它将做同样的事情枚举你的字段并创建一个检查所有字段的
equals
方法,然后选择n个素数,然后做你已经做过的事情来创建一个
hashCode
方法。

使用素数(它们不一定是“大”素数)的原因确实是为了避免公共因子

哈希代码由基于哈希的集合类使用,例如
HashSet
HashMap
。如果映射中对象的哈希代码尽可能不同,则它们工作得最好(如果这些对象的哈希代码相同,则它们必须做更多的工作来区分对象)


将用于生成带素数的组合哈希代码的部分的哈希代码相乘,可确保这些部分没有公因子,因此冲突的可能性较小(不同部分的哈希代码相互重叠)。

我这样做是正确的,那么,是否建议我在Boundary.hashCode()中使用与在底层Vector2f.hashCode()实现中使用的素数对不同的素数对?或者,如果我同时使用997和991,结果会是一样的吗?好了,因为XOR是旋转位,所以由XOR产生的整数不一定是素数(或非素数),这意味着如果我使用同一对素数就不重要了?我不完全确定;如果使用+而不是XOR,那么很明显-应该使用不同的素数。所以我这么做只是为了安全。请注意,XOR几乎类似于添加数字,但不带位(即
1^1=0
而不是
10
,带位向前)。我还没有想清楚这到底会如何影响结果。@Nick Wiggill我认为重要的是,被乘以的素数不是哈希表底层数组大小的一个因子。如果乘以17,数组的大小为34,那么所有对象都将位于位置0或17(导致大量碰撞)。使用^而不是+,存在一个主要危险。在一系列^中重复相同的元素将相互抵消。(N^Y^N=Y)由于它在每一步都被乘以,这一点得到了缓解。谢谢Samir,我不知道Eclipse有这个。