这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战
浅谈java中的equals覆盖
前文
本文仅为对于equals覆盖用法一些总结以及个人理解,难免有不清晰或不正确之处,还请见谅。
equals的覆盖
覆盖equals时一些需要满足的点
- 自反性:对于任何非空的对象x,x.equals(x) = true
- 对称性:对于非空对象x和y,x.equals(y) = y.equals(x)
- 传递性:对于非空对象x、y、z,如果x.equals(y),y.equals(z),那么x.equals(z)
- 一致性:对于非空对象x及y,只要equals的比较操作在对象中应用的信息未被修改,则多次调用x.equals(y)的结果一定会保持一致
- 对于任何非空的对象x,x.equals(null)一定等于false
覆盖euqals时总要覆盖hashCode
在覆盖了equals方法的对象中,需要保证哈希值方法同样被覆盖。由于equals标志着两个对象是否相等,如果equals方法被覆盖而哈希值方法未被覆盖,则可能出现两个对象经过equals计算结果为true,也就是两个对象被认为相等。而与此同时,由于对象的hashCode方法未被覆盖,二者的哈希值不一致。而这违反了java对于对象的一个规:如果两个对象equals比较结果相等,那么调用这两个对象的哈希值方法获得的值必须要保证相等。因此在覆盖equals方法时,必须要对哈希值方法进行覆盖。
进一步以代码进行举例: 现在我们有一个类:
public class Info extends Object{
public Info(int a, int b) {
this.a = a;
this.b = b;
}
public int a;
public int b;
@Override
public boolean equals(Object obj) {
return a + b == ((Info)obj).a + ((Info)obj).b;
}
}
根据这个例子进行分析,只要对象中a与b的和相等,我们就可以认为a与b是相同的对象。那么当二者作为map的key时,value应该是一致的。而当两个对象的a、b值分别是3,9以及4,8时,虽然二者equals相等了,但是实际上是完全不相同的两个对象。map.get(new Info(3,9))和map.get(new Info(4,8))不能保证相等。而map恰好是通过哈希值进行key值的定位寻找value值,因此在覆盖equals时,需要注意将哈希值方法进行覆盖。只有在重写该方法时注意对于哈希值的重写,才能避免此类意外的问题。
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。