我现在知道有几天内置的实用程序,例如来自Apache commons lang的HashCodeBuilder,但我试图自己了解如何实现它,并遇到了http://en.wikipedia.org/wiki/Java_hashCode()上Employee类的hascode函数的示例

在Google的任何地方,都建议使用相同的技术,例如将非零值与奇质数相乘,然后求和
与实例变量(为实例变量做)。

问题:-

1)为什么我们不能将employeeId作为hascode返回,因为它将是唯一的。它简单并且服务于hascode的目的。
如果不是唯一的,则可能我们需要这种技术。那正确吗?

2)即使雇员编号不是唯一的,为什么建议将其与奇质数相乘?为什么不带任何该死的整数
算不错?

更新:-

彼得·我跑了你提到的例子

[0、32、64、96、128、160、192、224、288、256、352、320、384]

[0、32、64、96、128、160、192、224、288、256、352、320、384]


  我假设现在的输出像预期的那样理解
  正如您在回答中提到的


[373、343、305、275、239、205、171、137、102、68、34、0]

[0、34、68、102、137、171、205、239、275、305、343、373]

正如您在评论中所建议的那样,该示例说明了即使是唯一的哈希码也可能会出现在同一存储桶中。这个怎么
例子证明了这种行为?您是说373代表整数,0代表integers2都出现在同一存储桶中吗?

在此示例中,素数有多大帮助?34将无济于事?

最佳答案

为什么我们不能将employeeId作为hascode返回,因为它将是唯一的。它简单并且服务于hascode的目的。如果不是唯一的,则可能我们需要这种技术。那正确吗?


它的唯一性并不重要。与素数相乘是将多个字段合并为一个hashCode的好方法,但是听起来您只有一个,所以不会有太大的区别。


  即使员工编号不是唯一的,为什么还要建议将其与奇质数相乘?为什么采用该死的整数不被认为是好的?


如果乘以偶数,hashCode的最低位是多少?它有多随机/有用?



注意:Integer的每个hashCode()都是唯一的,但是会得到正确的整数值组合,当它们减小为HashMap的容量时,它们实际上会映射到同一存储桶。在此示例中,条目的出现顺序与添加时相反,因为每个条目都映射到相同的存储桶。

HashSet<Integer> integers = new HashSet<>();
for (int i = 0; i <= 400; i++)
    if ((hash(i) & 0x1f) == 0)
        integers.add(i);
HashSet<Integer> integers2 = new HashSet<>();
for (int i = 400; i >= 0; i--)
    if ((hash(i) & 0x1f) == 0)
        integers2.add(i);
System.out.println(integers);
System.out.println(integers2);


static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}


版画

[373, 343, 305, 275, 239, 205, 171, 137, 102, 68, 34, 0]
[0, 34, 68, 102, 137, 171, 205, 239, 275, 305, 343, 373]

10-08 16:27