ref:https://www.cnblogs.com/TinyWalker/p/4834685.html

--------------------

编写equals方法的建议:

  1. 显示参数命名为otherObject, 稍后转化成other变量

    public boolean equals(Object otherObject)
    
  2. 检测this和otherObject是否是同一个对象的引用,是,返回true;
    if(this==otherObject){
        return true;
    }
  3. 检测otherObject是否为null, 是, 返回false;
    if(otherObject == null){
        return false;
    }
  4. 比较this和otherObject是否属于同一个类. 如果equals的语义在每个子类中有所改变,就使用getClass检测:
    if(getClass() != otherObject.getClass()){
        return false;
    }

    如果子类语义相同,使用instanceof检测:

    if(!(otherObject instanceof Employee)){
        return false;
    }
  5. 将otherObject转化为相对应的类型变量other
    Employee other = (Employee)otherObject;
    
  6. 对所需要的比较的数据域进行比较. 如果是基本数据类型,使用a==b比较; 如果是对象比较,调用Objects.equals(a, b)进行比较
    return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    

整个流程可以参照例1;

例1:雇员对象比较

如果两个雇员对象的姓名, 薪水和雇佣一样,就认为它们相等.重写equals方法如下:


public class Employee {

    private String name;
    private double salary;
    private Date hireDay;
    ... 
    @Override
    public boolean equals(Object obj) {
        // 如果为同一对象的不同引用,则相同
        if (this == obj) {
            return true;
        }
        // 如果传入的对象为空,则返回false
        if (obj == null) {
            return false;
        }         // 如果两者属于不同的类型,不能相等
        if (getClass() != obj.getClass()) {
            return false;
        }         // 类型相同, 比较内容是否相同
        Employee other = (Employee) obj;         return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }

 
 

注意,比较通过Objects中静态函数equals比较两个对象是否相等.该方法源码如下:

 public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

这样,当两个对象都为null时,返回true,例如,两个Employee对象的name都为null, 返回true; 如果第一个对象不为null,则调用a.equals(Object obj)方法

常见equals方法实现错误

1-未使用@override对覆盖超类的方法进行标记.


public class Employee {
    public boolean equals(Employee other) {     return Objects.equals(name, other.name) && salary ==other.salary && Objects.equals(hireDay, other.hireDay);
}

这个方法声明的显示参数类型是Employee. 其结果并没有覆盖Object中的equals方法,而是定义了一个完全无关的方法.为了避免发生类型错误,可以使用@override对覆盖超类的方法进行标记.

2-没有同时override hashcode()函数

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()
举例说明:


public override bool Equals(object obj)
{
if (!(obj is BalanceSheetReport expect))
return false; return this.EndSum == expect.EndSum
&& this.PreSum == expect.PreSum
&& this.SequenceId == expect.SequenceId
&& this.ProjectId == expect.ProjectId;
} public override int GetHashCode()
{
return this.PreSum.GetHashCode()
^ this.EndSum.GetHashCode()
^ this.SequenceId.GetHashCode()
^ this.ProjectId.GetHashCode();
}
 
 

Java 基础 - 如何重写equals()的更多相关文章

  1. 【Java基础】重写equals需要重写hashcode

    Object里的equals用来比较两个对象的相等性,一般情况下,当重写这个方法时,通常有必要也重写hashcode,以维护hashcode方法的常规协定,或者说这是JDK的规范,该协定声明相等对象必 ...

  2. java构造方法和重写equals

    Cell的构造函数 package Test; import java.util.Objects; public class Cell { int a; int b; public int getA( ...

  3. [转]java基础学习总结——equals方法

    一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 1 package cn.galc.test; 2 3 public class TestEquals { 4 public s ...

  4. java基础学习总结——equals方法

    一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 package cn.galc.test; public class TestEquals { public static vo ...

  5. 【java基础】 == 和 equals() 的区别

    ==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系呢? 首先,==号在比较基本数据类型(指的值类型)时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值: int x ...

  6. java中为什么重写equals时必须重写hashCode方法?

    在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...

  7. java removeAll和重写equals、hashcode引起的性能问题

    问题背景: 上周发现了一个spark job的执行时间从原来的10-15分钟延迟到了7个小时!wtf,这是出了什么事引起了这么大的性能问题!! 立马查看job的运行日志,发现多次运行都是在某一个固定的 ...

  8. 【原创】关于java对象需要重写equals方法,hashcode方法,toString方法 ,compareto()方法的说明

    在项目开发中,我们都有这样的经历,就是在新增表时,会相应的增加java类,在java类中都存在常见的几个方法,包括:equals(),hashcode(),toString() ,compareto( ...

  9. java 中为什么重写 equals 后需要重写 hashCode

    本文为博主原创,未经允许不得转载: 1. equals 和 hashCode 方法之间的关系 这两个方法都是 Object 的方法,意味着 若一个对象在没有重写 这两个方法时,都会默认采用 Objec ...

随机推荐

  1. XVIII Open Cup named after E.V. Pankratiev Stage 5: Eastern Grand Prix

    contest link easy: EI medium-easy: BCDGK medium: L medium-hard: AFH A. Artifacts B. Brackets and Dot ...

  2. mongo之find结果对象map实例处理

    find 找到结果对象列表 res = await SS_StudentsLeaveTask.find(filter=_filter) self.resData = map(lambda x: str ...

  3. 项目中UX设计1到2的设计提升总结

  4. react 父子组件传值

    父组件向子组件传递信息 父组件片段 constructor(props){ super(props) this.state={ message:"我是父组件传来的" } } ren ...

  5. Intellij IDEA gradle项目目录介绍

    Gradle简介 Java的构建,经历了从Ant-->Maven->Gradle的过程,每一次的进步,都是为了解决之前的工具带来的问题: Ant:Ant的功能虽然强大,但过于灵活,规范性不 ...

  6. asp.net MVC项目,localhost响应时间过长

    1.早上高高兴兴的吃完早餐,敲了几句代码,准备调试,竟然发现VS调试项目打开的很慢,最后报错如下图 2.那就很可能是IIS问题嘛,IIS重启了一下,还是不行,在地址栏输入localhost,如下图(本 ...

  7. __str__方法

    """str()就是可以自定义输出返回值,必须是str字符串""" class Dog: def __init__(self, name): ...

  8. JAVA错误:Exception in thread "main" java.lang.NullPointerException

    JAVA错误:Exception in thread "main" java.lang.NullPointerException例如: Exception in thread &q ...

  9. Dart编程语法

    语法定义了一组用于编写程序的规则.每种语言规范都定义了自己的语法.Dart语法有如下内容组成: 变量和运算符 类 函数 表达式和代码块 判断和循环结构 注释 库和包 类型定义 数据结构表示:集合/泛型 ...

  10. NX二次开发-UFUN关闭STL文件函数UF_STD_close_stl_file

    NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <u ...