equals() and hashCode() in Java
equals()
1 | // defined in Object class |
equals()的Override, 应该遵循以下原则:
-
自反性:x.equals(x) return
true
-
对称性:y.equals(x) return
true
<=> x.equals(y) returntrue
-
传递性:x.equals(y) return
true
, y.equals(z) returntrue
=> x.equals(z) returntrue
-
一致性:无论对**x.equals(y)**调用多少次,结果都应该一致; 除非equals()中使用到的属性被更改了
-
非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
hashCode()
1 | // defined in Object class |
- 在某个Java程序的
一次执行过程
中, 只要equals()使用的属性
没有被改变, 那么同一个对象
无论调用多少次hashCode(), 其返回的值都必须一致
- 在同一个Java程序的
多次执行过程
中, 一个对象的hashCode()返回值,不必保持相同
Override Rule
为什么重写equals()的时候,必须重写hashCode()?
- Java的general contract规定, 相等的对象,必须具有相同的hash code
- Object对象默认实现的hashCode(), 是为每一个对象返回不同的值
equals()和hashCode()的Override, 应该遵循以下原则:
-
若
o1.equals(o2)
为true, 则o1.hashCode() == o2.hashCode()
为true -
反之, 不成立
-
equals不相等的两个对象, hashCode可能相等
-
However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
1 | o1.equals(o2) |
Implementation
1 | public class User { |
Another solution: hashCode()
1 |
|
Objects.hashCode()
1 | public static int hashCode( { Object ... objects) |
Arrays.hashCode()
1 | public static int hashCode(Object a[]) { |
Why is the multiplier 31?
选择质数
, 减少哈希碰撞(Hash Collision)- 不选择
较小的质数
, e.g. 2; 因为冲突率依然很高 - 不选择
较大的质数
, e.g. 101; 会产生溢出 31 * i
可被jvm优化为(i << 5) - i