Java中equals()方法详细解析

本文主要内容:

  • 覆盖equals() 方法需要遵守哪些通用规定

  • 什么时候该重写equals()方法

  • 重写equals()方法有哪些特征

  • 重写一个equals()方法的步骤

  • 为什么重写equals()方法时要先重写hashCode()方法

    我们知道equals()方法是顶级类 Object下的一个非 final方法,我们在使用的每个Java类都是要继承Object类的,那么任何一个类在覆盖这些方法的时候,都有责任遵守这个约定.

1 、覆盖equals时要遵循的约定

  • 类的每个实例本质是唯一的,也就是每个 new Object()这个这个类的实例是唯一一个,在创建一个对象实例则不是相同的
  • 不关心类是否提供了逻辑相等的测试功能。使用Random生成随机数时,不需要关系是否生成了两个逻辑数是否相同,直接就是不同的对象
image.png

输出:

image.png
  • 超类已经重写了equals()方法,从超类继承过来的行为对于子类也是合适的
    例如Map实现了equals方法则直接可以使用equals方法比对两个map是否相等
image.png
image.png
  • 类是私有的或是包级别私有的,可以确定它的equals方法永远不会被调用

2、什么时候该重写equals方法

如果类具有自己特有的“”逻辑特性“”,而且超类还没有覆盖equals以实现期望的行为. 及我们不想知道它是否在内存中指向的是否一个对象,我们想判断它的逻辑值是否相等
例如: 一个雇员实体类里面有员工姓名、薪水等,我想知道2个雇员对象是否是逻辑上相等

3.如何重写一个equals方法了

覆盖Object方法中equals方法需要遵循以下几个规范
  • 自反性. 对于任何非null的引用值x, x.equals(x)必须返回true. 通俗的讲自己跟自己比较返回true
  • 对称性 对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)也必须返回true
  • 传递性 对于任何非null的引用值x、y、z,如果x.equals(y)返回true并且y.equals(z)也返回true,那么x.equals(z)也必须返回true
  • 一致性 对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致的返回true,或者一致的返回false
  • 非空性 对于任何非null的引用值x,x.equals(null)必须返回false

如何实现一个equals()方法:

  • 1.使用==操作符检查“”参数是否为这个对象的引用”
  • 2.使用 instanceof 操作符检查"检查参数是否为正确的类型"
  • 3.把参数转换成正确的类型
  • 4.对于该类中的没给 “关键”域,检查参数中的域是否与该对象中对应的域相匹配相匹配
package com.minglangx.object;

import java.util.Date;
import java.util.Objects;

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;
//        }
        
        if( !(obj instanceof Employee) ) {
            return false;
        }

        // 类型相同, 比较内容是否相同
        Employee other = (Employee) obj;

        return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }
} 
4为什么重写equals方法之前要重写hashCode方法

因为 Object规范中说到: 相等的对象必须具有相等的散列码
因为hashCode散列码的目的是为了HashSet、HashMap、HashTable比较的时候缩小范围空间,它只是返回一个散列整数然后根据散列码去散列桶中查找对象区间。它不保证对象是否是相等的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容