我有一个实现了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元组向量(start& end)创建一个好的hashCode()。我的问题:这个hashCode()实现是否正常工作?
(请注意,我在后一个hashCode()实现中使用了2个不同的素数;我不知道这是否有必要但是为了安全而不是更好,当我试图避免常见因素时,我猜 - 因为我假设这就是素数在散列函数中很受欢迎的原因。)
答案 0 :(得分:17)
这是正常做法。这看起来很合理。如果你正在使用Eclipse,你会发现它可以为你生成equals
和hashCode
- 只需检查 Source 菜单。它将执行相同的操作 - 枚举您的字段并创建一个equals
方法来检查所有字段,然后选择 n 素数并执行您创建的{{1方法。
答案 1 :(得分:3)
使用素数(它们不一定是“大”素数)的原因确实是为了避免常见因素。
哈希代码由基于哈希的集合类使用,例如HashSet
和HashMap
。如果地图中对象的哈希码尽可能不同,它们的效果最好(如果这些对象的哈希码相同,它们必须做更多工作来区分对象)。
将用于组合哈希码的部分的哈希码与素数相乘可确保部件不具有公共因子,因此冲突的可能性较小(关于不同部分的哈希码相互重叠) )。