关于重写equals();

转载 2016年08月28日 15:33:14
      

今天复习了下 《Effective Java》的第八条,特地做下笔记。

包括:

一. 为什么要覆盖 equals

二. 覆盖 equals 的通用约定

三. 如何覆盖 equals (重点)



一. 为什么要覆盖 equals:

简单来说,就是为了要逻辑相等。两个对象,不管他们的内存地址,关心的只是他们的内容是否相等。

二. 覆盖 equals 的通用约定:

覆盖的时候不能瞎覆盖,不能随便写个 @override 就完事了,需要满足 自反性,对称性,传递性,一致性,以及对于任何非 null 的引用值 x,x.equals(null) 必须返回 false

怎么说呢,比如说

1. 自反性,a.equals(a) ;

2. 对称性,a.equals(b) 同时也要 b.equals(a) 。

3. 传递性,这个就是考虑到继承的情况,比如说像下面这样编译的时候


可以看到warning:总是想为我生成 equals 和 hasCode 方法。因为我继承了父类,那么这个类的 equals 方法是父类的,使用该类的 equals 将调用父类的 equals,所以说该类的这些成员变量都不会比较了。 例如:这里有一个 ClassA,重写 equals 方法:
public class ClassA {
    private int numA;
    public ClassA(int numA){
        this.numA = numA;
    }

    @Override
    public boolean equals(Object object) {
        if(object instanceof ClassA){
            if(numA == ((ClassA) object).getNumA()){
                return true;
            }
        }
        return false;
    }

    public int getNumA(){
        return numA;
    }
}

然后有 ClassB,继承了 ClassA,实际上ClassB用的就是ClassA的equals方法:

public class ClassB extends ClassA{
    public ClassB(int numA,int numB){
        super(numA);
        this.numB = numB;
    }
    private int numB;
}

那么,在使用的时候,如下:

public class Main {
public static void main(String args[]) {
        ClassB classB1 = new ClassB(1,2);
        ClassB classB2 = new ClassB(1,3);

        System.out.println(classB1.equals(classB2));
    }
}

就会输出 true 了。

那么,这点写的有点多,主要也是为了提醒,当我们写equals方法的时候,记得要 call super 的 equals 方法,然后再比较本类的 equals 方法。

像 lombok 就很贴心的提供了 @EqualsAndHashCode(callSuper=true) 注解。

4. 一致性,调多次都是返回这个。

5. 对于任何非 null 的引用值x, x.equals(null) 必须返回 false。

三. 如何覆盖 equals (重点):

如何 equals 方法还要自己来覆盖,那么就真 out 了。参考这里 JAVA如何快速重写int hashcode()? - 编程@用心阁 提到了几种方法,有 谷歌的,apache的,jdk的,以及IDE的。本人在工作中就是使用 lombok 的 @EqualsAndHashCode 注解。官方有其介绍 @EqualsAndHashCode

那么,如何非要自己实现,根据《Effective Java》,有几点需要注意:

1. 使用 == 检查 引用是否相等,引用相等就直接返回 true了,因为内存地址都一样了,具体内容也肯定一样,就不用比较了。

2. instanceOf 判断是否为正确的类型,如果不是,那么直接返回 false。都不是同一个类型的东西,就甭比较了。

3. 把需要比较的 Object 转换成该类(由于 instanceOf,所以肯定能转换的),转换之后,再对每个关键域进行比较。

1 和 2 都是为了性能考虑,3 就是真正的比较。

(完)



作者:鼬自来晓
链接:https://zhuanlan.zhihu.com/p/22208465
来源:知乎
著作权归作者所有。

                                                                                                                                                                                              

重写equals要遵守的规则

首先要注意重写equals必须重写hashCode (1.1)自反性:对于任何非null的引用值x,x.equals(x)=true (1.2)对称性:对于任何非null的引用x,y,x.equals...
  • wode19920311
  • wode19920311
  • 2016年02月21日 12:50
  • 624

java 中 重写equals方法的用处

以前只是在学习java的时候遇到了equals方法,对于重写equals有什么用是一点也不清楚,今天在项目在做比对的时候出了问题, 就试着重写了equals方法,结果就解决了问题。 在开发的时...
  • footballclub
  • footballclub
  • 2015年01月05日 14:33
  • 2593

为什么要重写hashcode和equals方法?

为什么要重写hashcode和equals方法? 相信很多小伙伴被这个问题给困扰很久了,下面我就给大家详细说一下我的理解吧~ 因为默认的hequals方法是Object的方法,比较的是内存...
  • world6
  • world6
  • 2016年08月05日 11:42
  • 1408

详解重写equals()方法就必须重写hashCode()方法的原因

重写的作用: 如果重写(用于需求,比如建立一个Person类,比较相等我只比较其属性身份证相等就可不管其他属性,这时候重写)equals,就得重写hashCode,和其对象相等保持一...
  • u013679744
  • u013679744
  • 2017年02月25日 10:04
  • 2838

Java Set详解及实例,重写equals()和hashCode()

详细讲解HashSet的特点,HashSet元素的存储原理,HashSet实例
  • zcl_666
  • zcl_666
  • 2016年09月19日 10:44
  • 2515

如何正确的重写equals() 和 hashCode()方法

equals和hashCode重写技巧
  • zzg1229059735
  • zzg1229059735
  • 2016年05月25日 15:36
  • 6496

Hibernate中为什么要重写equals()和hashCode()这两个方法

Hibernate中为什么要重写equals()和hashCode()这两个方法
  • yuripe1995
  • yuripe1995
  • 2015年10月17日 17:34
  • 315

重写equals时还必须重写hashcode方法,详解

http://www.cnblogs.com/happyPawpaw/p/3744971.html http://www.jb51.net/article/42408.htm http:/...
  • basycia
  • basycia
  • 2016年07月31日 22:03
  • 4193

为什么重写equals方法,一定要重写HashCode方法?(

主要原因是默认从Object继承来的hashCode是基于对象的ID实现的。 如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相...
  • agfagafsdfas
  • agfagafsdfas
  • 2014年04月13日 20:14
  • 597

同时重写equals和hashCode的意义

使用过eclipse等IDE集成环境的朋友都知道, 当我们需要判断两个对象是否相等时, 往往会想到重写 equals 方法。为此, eclipse代码自动生成工具还提供了非常便捷的功能(右健->Sou...
  • linchunquan
  • linchunquan
  • 2014年03月07日 17:36
  • 1237
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于重写equals();
举报原因:
原因补充:

(最多只允许输入30个字)