202111-14更文-浅谈java中的equals覆盖

109 阅读2分钟

这是我参与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时,需要注意将哈希值方法进行覆盖。只有在重写该方法时注意对于哈希值的重写,才能避免此类意外的问题。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。