将Java哈希码组合成“主”哈希码
我有一个实现了hashCode()的vector类。 它不是由我编写的,而是使用2个素数来乘以2个向量分量,然后对它们进行异或运算。 这里是:
/*class Vector2f*/ ... public int hashCode() { return 997 * ((int)x) ^ 991 * ((int)y); //large primes! }
…因为这是来自一个已建立的Java库,我知道它的工作正常。
然后我有一个Boundary类,它包含2个向量,“start”和“end”(表示一行的端点)。 这两个向量的值是边界的特征。
/*class Boundary*/ ... public int hashCode() { return 1013 * (start.hashCode()) ^ 1009 * (end.hashCode()); }
在这里,我试图为构成这个边界的唯一2元组向量(开始和结束)创建一个好的hashCode()。 我的问题:这个hashCode()实现是否有效?
(请注意,我在后一个hashCode()实现中使用了2个不同的素数;我不知道这是否有必要但是为了安全而不是更好,当我试图避免常见因素时,我猜 – 因为我认为这是为什么素数很受哈希函数的欢迎。)
这是正常做法。 这看起来很合理。 如果你正在使用Eclipse,你会发现它可以为你生成equals
和hashCode
– 只需检查Source菜单。 它将执行相同的操作 – 枚举您的字段并创建一个检查所有字段的equals
方法,然后选择n个素数并执行您创建的hashCode
方法。
使用素数(它们不一定必须是“大”素数)的原因确实是为了避免共同因素。
哈希代码由基于哈希的集合类(如HashSet
和HashMap
。 如果地图中对象的哈希码尽可能不同,它们的效果最好(如果这些对象的哈希码相同,则必须做更多工作来区分对象)。
将用于生成组合哈希码的部分的哈希码与素数相乘可确保部件不具有公共因子,因此冲突的可能性较小(关于不同部分的哈希码相互重叠)。