0

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

在谷歌的任何地方,都建议使用相同的技术,例如将非零值与奇数素数相乘,然后将其与实例变量相加(对实例变量执行此操作)。

问题:-

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

2)即使员工ID不是唯一的,为什么建议乘以奇数素数?为什么取任何该死的整数都不被认为是好的?

更新:-

彼得我运行了你提到它打印的例子

[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 最终在同一个桶中吗?

在这个例子中质数有什么帮助,而 34 又如何没有帮助?

4

1 回答 1

2

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

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

即使员工 id 不是唯一的,为什么它建议乘以奇数素数?为什么取任何该死的整数都不被认为是好的?

如果乘以偶数,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]
于 2013-10-06T13:44:31.793 回答