我现在知道有几天内置的实用程序,例如来自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]