Java中equals()方法詳細(xì)解析

本文主要內(nèi)容:

  • 覆蓋equals() 方法需要遵守哪些通用規(guī)定

  • 什么時候該重寫equals()方法

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

  • 重寫一個equals()方法的步驟

  • 為什么重寫equals()方法時要先重寫hashCode()方法

    我們知道equals()方法是頂級類 Object下的一個非 final方法,我們在使用的每個Java類都是要繼承Object類的,那么任何一個類在覆蓋這些方法的時候,都有責(zé)任遵守這個約定.

1 、覆蓋equals時要遵循的約定

  • 類的每個實(shí)例本質(zhì)是唯一的,也就是每個 new Object()這個這個類的實(shí)例是唯一一個,在創(chuàng)建一個對象實(shí)例則不是相同的
  • 不關(guān)心類是否提供了邏輯相等的測試功能。使用Random生成隨機(jī)數(shù)時,不需要關(guān)系是否生成了兩個邏輯數(shù)是否相同,直接就是不同的對象
image.png

輸出:

image.png
  • 超類已經(jīng)重寫了equals()方法,從超類繼承過來的行為對于子類也是合適的。
    例如Map實(shí)現(xiàn)了equals方法則直接可以使用equals方法比對兩個map是否相等
image.png
image.png
  • 類是私有的或是包級別私有的,可以確定它的equals方法永遠(yuǎn)不會被調(diào)用

2、什么時候該重寫equals方法

如果類具有自己特有的“”邏輯特性“”,而且超類還沒有覆蓋equals以實(shí)現(xiàn)期望的行為. 及我們不想知道它是否在內(nèi)存中指向的是否一個對象,我們想判斷它的邏輯值是否相等
例如: 一個雇員實(shí)體類里面有員工姓名、薪水等,我想知道2個雇員對象是否是邏輯上相等

3.如何重寫一個equals方法了

覆蓋Object方法中equals方法需要遵循以下幾個規(guī)范
  • 自反性. 對于任何非null的引用值x, x.equals(x)必須返回true. 通俗的講自己跟自己比較返回true
  • 對稱性 對于任何非null的引用值x和y,當(dāng)且僅當(dāng)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的比較操作在對象中所用的信息沒有被修改,多次調(diào)用x.equals(y)就會一致的返回true,或者一致的返回false
  • 非空性 對于任何非null的引用值x,x.equals(null)必須返回false

如何實(shí)現(xiàn)一個equals()方法:

  • 1.使用==操作符檢查“”參數(shù)是否為這個對象的引用”
  • 2.使用 instanceof 操作符檢查"檢查參數(shù)是否為正確的類型"
  • 3.把參數(shù)轉(zhuǎn)換成正確的類型
  • 4.對于該類中的沒給 “關(guān)鍵”域,檢查參數(shù)中的域是否與該對象中對應(yīng)的域相匹配相匹配
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;
        }

//        // 如果兩者屬于不同的類型,不能相等 這種情況只能是對象具有相同的實(shí)現(xiàn)才能使用
//        if (getClass() != obj.getClass()) {
//            return false;
//        }
        
        if( !(obj instanceof Employee) ) {
            return false;
        }

        // 類型相同, 比較內(nèi)容是否相同
        Employee other = (Employee) obj;

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

因?yàn)?Object規(guī)范中說到: 相等的對象必須具有相等的散列碼
因?yàn)閔ashCode散列碼的目的是為了HashSet、HashMap、HashTable比較的時候縮小范圍空間,它只是返回一個散列整數(shù)然后根據(jù)散列碼去散列桶中查找對象區(qū)間。它不保證對象是否是相等的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容