java重寫equals()方法和hashCode()方法

1.equals()方法和hashCode()方法是什麼?java

    equals()和hashCode()都是是Java中萬物之源Object類中的方法;
    equals方法用於比較兩個對象是否相同,Object類中equals方法的實現是比較引用地址來判斷的對象是不是同一個對象,經過覆蓋該方法能夠實現自定義的判斷規則;
    hashCode是jdk根據對象的地址或者字符串或者數字計算該對象的哈希碼值的方法。程序員

2.爲何要重寫equals()方法?框架

    Object類中equals方法比較的是兩個對象的引用地址,只有對象的引用地址指向同一個地址時,才認爲這兩個地址是相等的,不然這兩個對象就不想等。
    若是有兩個對象,他們的屬性是相同的,可是地址不一樣,這樣使用equals()比較得出的結果是不相等的,而咱們須要的是這兩個對象相等,所以默認的equals()方法是不符合咱們的要求的,這個時候咱們就須要對equals()方法進行重寫以知足咱們的預期結果。
    在java的集合框架中須要用到equals()方法進行查找對象,若是集合中存放的是自定義類型,而且沒有重寫equals()方法,則會調用Object父類中的equals()方法按照地址比較,每每會出現錯誤的結果,此時咱們應該根據業務需求重寫equals()方法。ide

3.爲何要重寫hashCode()方法?性能

    hashCode()方法用於散列數據的快速存儲,HashSet/HashMap/Hashtable類存儲數據時都是根據存儲對象的hashcode值來進行分類存儲的,通常先根據hashcode值在集合中進行分類,在根據equals()方法判斷對象是否相同。
    HashMap對象是根據其Key的hashCode來獲取對應的Value。
    生成一個好的hashCode值能提升HashSet查找的性能,差的hashCode值不但不能提升性能,甚至可能形成錯誤。好比hashCode方法中返回常量,會讓,HashSet的查找效率退化爲List集合的查找效率;hashCode方法中返回隨機數,會讓查找結果變的不可預測。
    好的hashCode生成方式是讓對象中的關鍵屬性與質數相乘,並將積相加獲取。this

4.爲何java中在重寫equals()方法後必須對hashCode()方法進行重寫?編碼

    爲了維護hashCode()方法的equals協定,該協定指出:若是根據 equals()方法,兩個對象是相等的,那麼對這兩個對象中的每一個對象調用 hashCode方法都必須生成相同的整數結果;而兩個hashCode()返回的結果相等,兩個對象的equals()方法不必定相等。
    HashMap對象是根據其Key的hashCode來獲取對應的Value。
    在重寫父類的equals()方法時,也重寫hashcode()方法,使相等的兩個對象獲取的HashCode值也相等,這樣當此對象作Map類中的Key時,兩個equals爲true的對象其獲取的value都是同一個,比較符合實際。.net

5.重寫equals()方法:code

重寫equals方法須要遵循Java以下規則,不然編碼行爲會難以揣測:對象

    自反性:對於任意的對象x,x.equals(x)返回true(本身必定等於本身);
    對稱性:對於任意的對象x和y,若x.equals(y)爲true,則y.equals(x)亦爲true;
    傳遞性:對於任意的對象x、y和z,若x.equals(y)爲true且y.equals(z)也爲true,則x.equals(z)亦爲true;
    一致性:對於任意的對象x和y,x.equals(y)的第一次調用爲true,那麼x.equals(y)的第二次、第三次、第n次調用也均爲true,前提條件是沒有修改x也沒有修改y;
    對於非空引用x,x.equals(null)永遠返回爲false。

重寫代碼以下:


    @Override
    public boolean equals(Object o) {
        //自反性
        if (this == o) return true;
        //任何對象不等於null,比較是否爲同一類型
        if (!(o instanceof Person)) return false;
        //強制類型轉換
        Person person = (Person) o;
        //比較屬性值
        return getId() == person.getId() &&
                Objects.equals(getName(), person.getName()) &&
                Objects.equals(getSex(), person.getSex());
    }

 

6.重寫hashCode()方法:

HashMap對象是根據其Key的hashCode來獲取對應的Value。
在重寫父類的equals方法時,也重寫hashcode方法,使相等的兩個對象獲取的HashCode也相等,這樣當此對象作Map類中的Key時,兩個equals爲true的對象其獲取的value都是同一個,比較符合實際。

重寫hashCode()方法須要遵循hashCode()協定:

    一致性:在Java應用程序執行期間,在對同一對象屢次調用hashCode方法時,必須一致地返回相同的整數,前提是將對象進行hashcode比較時所用的信息沒有被修改。
    equals:若是根據equals()方法比較,兩個對象是相等的,那麼對這兩個對象中的每一個對象調用hashCode()方法都必須生成相同的整數結果,注:這裏說的equals()方法是指Object類中未被子類重寫過的equals()方法。
    附加:若是根據equals()方法比較,兩個對象不相等,那麼對這兩個對象中的任一對象上調用hashCode方法不必定生成不一樣的整數結果。可是,程序員應該意識到,爲不相等的對象生成不一樣整數結果能夠提升哈希表的性能。

重寫代碼以下:


    @Override     public int hashCode() {         return Objects.hash(getId(), getName(), getSex());     }

相關文章
相關標籤/搜索