为什么java hashcode 实现31 * x + y 比x + y 好?

200*_*0OK 8 java hashcode

我对关于哪种哈希码实现更好的 Java 面试问题感到困惑。我们有一个类 Point {int x, y; }. 为什么这个类的 hashcode 31 * x + y 的实现比 x + y 好?正确的答案是“乘数创建了哈希码值对字段处理顺序的依赖,这最终会产生更好的哈希函数”。但我不明白为什么处理的顺序是这里的重点,因为当我执行 point1.equals(point2); 时,整个表达式 31 * x + y 正在计算;并且无论它以何种顺序发生。我错了吗?

Jea*_*nès 8

如果使用x+y那么如何区分点(3,4)和(4,3)?两者都将具有相同的哈希码...

现在虽然31 * x + y不会完美,但在同样的情况下,它会好得多。

注意:根据散列的定义,没有完美的散列。唯一的事情就是分析给定的散列函数发生了什么样的冲突。在几何情况下,第一个为非常简单和常用的对称属性引入了碰撞。因此,在非常常见的情况下,可能会有太多的冲突。

  • @Titulum,然后其他一些点对将相互碰撞,例如。(0,31) 和 (37, 0) :) (2认同)

chr*_*ke- 6

假设您有两个字符串属性prop1andprop2和两个对象:

A: {prop1="foo", prop2="bar"}
B: {prop1="bar", prop2="foo"}
Run Code Online (Sandbox Code Playgroud)

这些显然是不同的值,设置哈希码来区分它们很有用。如果您只需添加属性散列码在一起,你会得到两个相同的数值AB。相反,通过乘法和相加,哈希码将根据属性序列而不同。

看来您可能稍微误解了该建议:乘加的目的是创建对对象内属性语义顺序的依赖,而不是计算执行顺序