Object類的equals方法

1、Object類中默認(rèn)的實(shí)現(xiàn)方式是:return this == obj。也就是說,只有this和obj引用同一個(gè)對(duì)象的時(shí)候,才會(huì)返回true

2、equals方法需要滿足以下規(guī)則:
(1)、自反性:x.equals(x)應(yīng)該返回true;
(2)、對(duì)稱性: x.equals(y)為true,那么y.equals(x)也為true;
(3)、傳遞性:x.equals(y)為true,并且y.equals(z)為true,那么x.equals(z)也應(yīng)該為true;
(4)、 一致性: x.equals(y)的第一次調(diào)用為true,那么第二次、第三次、第n次調(diào)用也應(yīng)該為true,前提條件是在比較之前沒有修改x也沒有修改y;
(5)、對(duì)非空引用x, x.equals(null)返回false。

3、用一個(gè)demo簡(jiǎn)單介紹一下equals方法的編寫

public class EqualsDemo
{
    private String name;
    private int age;

    public EqualsDemo()
    {
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;

        // 能執(zhí)行到這里,說明obj和this同類且非null。
        EqualsDemo p = (EqualsDemo) obj;
        return age == p.age && (name == p.name || (name != null && name.equals(p.name)));

    }
    
    @Override
    public int hashCode()
    {
        // 重寫equals,也必須重寫hashCode。具體后面介紹。
    }

}
  • EqualsDemo的對(duì)象有二個(gè)字段,name和age,這2個(gè)字段代表了對(duì)象的狀態(tài),也會(huì)用在equals方法中作為評(píng)判的依據(jù)。

  • 在equals方法中,首先將obj(傳入對(duì)象的引用)和this做比較,節(jié)約執(zhí)行時(shí)間,如果this 和 obj是 對(duì)同一個(gè)堆對(duì)象的引用,那么,他們一定是相等的。

  • 接著,判斷obj是否為null,如果是bull,一定不相等,因?yàn)榧热划?dāng)前對(duì)象this能調(diào)用equals方法,那么它一定不是null,非null和null當(dāng)然不相等。

  • 然后,比較2個(gè)對(duì)象的運(yùn)行時(shí)類,是否為同一個(gè)類。不是同一個(gè)類,則不相等。getClass返回的是 this 和obj的運(yùn)行時(shí)類的引用。如果他們屬于同一個(gè)類,則返回的是同一個(gè)運(yùn)行時(shí)類的引用。注意,一個(gè)類也是一個(gè)對(duì)象。

  • 也有人使用下面方法替代上面比較運(yùn)行時(shí)類的寫法,應(yīng)該避免這樣做:

if(!(obj instanceof EqualsDemo))
     return false; // avoid 避免!

因?yàn)樗`反了規(guī)則中的對(duì)稱性,例如;假設(shè)Dog類擴(kuò)展了Animal類。這就會(huì)導(dǎo)致

animal.equls(dog) 返回true
dog.equals(animal) 返回false

僅當(dāng)EqualsDemo類沒有子類的時(shí)候,這樣做才能保證是正確的。

  • 按照第一種方法實(shí)現(xiàn),那么equals只能比較同一個(gè)類的對(duì)象,不同類對(duì)象永遠(yuǎn)是false。但這并不是強(qiáng)制要求的。一般我們也很少需要在不同的類之間使用equals。

  • 在具體比較對(duì)象的字段的時(shí)候,對(duì)于基本值類型的字段,直接用 == 來比較(注意浮點(diǎn)數(shù)的比較,這是一個(gè)坑)對(duì)于引用類型的字段,你可以調(diào)用他們的equals,當(dāng)然,你也需要處理字段為null 的情況。對(duì)于浮點(diǎn)數(shù)的比較,我在看Arrays.binarySearch的源代碼時(shí),發(fā)現(xiàn)了如下對(duì)于浮點(diǎn)數(shù)的比較的技巧:

if ( Double.doubleToLongBits(d1) == Double.doubleToLongBits(d2) ) //d1 和 d2 是double類型

if(  Float.floatToIntBits(f1) == Float.floatToIntBits(f2)  )      //f1 和 f2 是d2是float類型
  • 并不總是要將對(duì)象的所有字段來作為equals 的評(píng)判依據(jù),那取決于你的業(yè)務(wù)要求。比如你要做一個(gè)家電功率統(tǒng)計(jì)系統(tǒng),如果2個(gè)家電的功率一樣,那就有足夠的依據(jù)認(rèn)為這2個(gè)家電對(duì)象等價(jià)了,至少在你這個(gè)業(yè)務(wù)邏輯背景下是等價(jià)的,并不關(guān)心他們的價(jià)錢啊,品牌啊,大小等其他參數(shù)。

  • 最后需要注意的是,equals 方法的參數(shù)類型是Object,不要寫錯(cuò)!

注釋以上部分內(nèi)容來自:
lulipro

上一篇:ArrayList與LinkedList比較
下一篇:關(guān)于Object類的hashcode()方法的特點(diǎn)

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

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

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