為什么重寫equals方法?為什么重寫hashCode方法?

日常開發(fā)中,不會(huì)刻意去重寫equals和hashCode方法,隨著業(yè)務(wù)代碼越寫越多,對(duì)于這兩個(gè)方法的記憶就消退了,然而底層知識(shí)才能撐起上層建筑,所以拿出來(lái)復(fù)習(xí)下;

這里兩個(gè)方法都來(lái)自于Object;
1.equals:這里equals是一個(gè)native方法,返回這個(gè)對(duì)象的hash code,HashMap受益于該方法;

/**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
*/
  public native int hashCode();

2.hashCode:可以看到equals方法其實(shí)就是比較了地址;

 public boolean equals(Object obj) {
        return (this == obj);
    }

辣么,問(wèn)題來(lái)啦,為什么要重寫equals?
當(dāng)我們?cè)诒容^兩個(gè)自定義對(duì)象是否相等時(shí)候,往往是比較他們的字段值是否都相等;而equals本身比較的是地址,創(chuàng)建兩個(gè)自定義對(duì)象,對(duì)象被分配在堆中,地址是不同的。所以重寫equals方法讓對(duì)象比較成為了可能;

然后呢?為什么要重寫hashCode方法呢?
根據(jù)上面源碼的注釋,我們可以看到,hashCode方法收益與HashMap,這里就從HashMap的put和contains方法來(lái)了解:

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.hashCode();

        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

可以看到這里在存入值得時(shí)候,會(huì)調(diào)用hashCode來(lái)獲取對(duì)應(yīng)Entry數(shù)組所在位置,并循環(huán)查找,怎么查找呢?調(diào)用了自定義對(duì)象的equals方法來(lái)查找,這樣來(lái)實(shí)現(xiàn)對(duì)Map的操作;
是不是有點(diǎn)小疑問(wèn)?這里解釋一下,兩個(gè)不同的對(duì)象可能hashCode相同,但是絕對(duì)不equals,而hashCode的計(jì)算效率最高,equals方法還需要去走自己重寫的內(nèi)部邏輯,所以,根據(jù)這個(gè)特性,先比較hashCode,如果相同,再比較equals,從而提高了HashMap的效率。
而HashMap的contains方法也是如此實(shí)現(xiàn)的:

 public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }
final Entry<K,V> getEntry(Object key) {
        if (size == 0) {
            return null;
        }

        int hash = (key == null) ? 0 : hash(key);
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

同樣,HashSet內(nèi)部實(shí)現(xiàn)就是基于HashMap;
所以:什么場(chǎng)景下需要重寫這兩個(gè)方法呢?
1.使用Set集合操作自定義對(duì)象的時(shí)候;
2.使用自定義對(duì)象作為HashMap的key時(shí)(當(dāng)然很少,而Set就是其中一個(gè)實(shí)現(xiàn));

雖然這些很基礎(chǔ),但都是通往上層的基石;

最后編輯于
?著作權(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)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,853評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,887評(píng)論 11 349
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,224評(píng)論 0 16
  • 前言 首先再次強(qiáng)調(diào)hashcode (==)和equals的真正含義 equals:是否同一個(gè)對(duì)象實(shí)例。注意,是“...
    小小亭長(zhǎng)閱讀 697評(píng)論 0 0
  • 遇到的問(wèn)題: 在請(qǐng)求后臺(tái)時(shí),狀態(tài)碼返回是200,看到返回的內(nèi)容卻是nil,在使用其它的請(qǐng)求工具嘗試,返回是正常的。...
    Hing0000閱讀 5,546評(píng)論 0 4

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