1

每当我使用 eclipse 'source' 菜单覆盖 hashcode() 时,它会在类中生成以下代码

final int prime = 31;
int result = 1;
result = prime * result + ((fieldName1== null) ? 0 : fieldName1.hashCode());
result = prime * result + ((fieldName2== null) ? 0 : fieldName2.hashCode());

谁能解释为什么它要进行所有这些计算(乘法然后加法),为什么它没有简单地返回

fieldName.hashCode();
or
fieldName2.hashCode();

?

4

3 回答 3

0

为什么它没有简单地返回 fieldName.hashCode();或 fieldName2.hashCode()

要了解原因,您还必须检查实施equals()并了解实施的约束hashCode()

  1. 实现必须为比较hashCode()为相等的对象返回相等的值: if x.equals(y)then x.hashCode() == y.hashCode()

  2. 一个好的 hashCode()实现应该很少为不相等的对象返回相同的哈希码:如果!x.equals(y)那么经常 x.hashCode() != y.hashCode()

  3. Eclipse 生成的equals()实现同时检查fileName1filename2. 如果两个对象中的任何一个不同,则该方法将认为这两个对象是不等价的。

  4. 因此,如果两者不同,相应的良好 hashCode()实现应该产生不同的哈希码值。fileName1 fileName2

  5. 因此,相应的良好 hashCode()实现应该使用fileName1.hashCode() and fileName2.hashCode()

于 2013-06-14T12:19:20.100 回答
0

乘法减少碰撞

请阅读约书亚·布洛赫

选择值 31 是因为它是一个奇数素数。如果它是偶数并且乘法溢出,则信息将丢失,因为乘以 2 相当于移位。使用素数的优势不太明显,但它是传统的。31 的一个很好的特性是乘法可以用移位和减法代替以获得更好的性能:31 * i == (i << 5) - i。现代虚拟机自动进行这种优化。

于 2013-06-14T11:58:50.963 回答
0

它在这里解释。

基本上,您在乘法中使用素数来更好地分布散列值。然后更好HashSetHashMap工作,因为它们根据哈希值进行分配。散列值分布不均会导致许多冲突。

于 2013-06-14T12:01:30.157 回答