Effective Java -- 重寫equals方法時總要重寫hashCode方法

在Java的Object 的規範中,有一點說的是—— 相等的對象必須有相等的散列碼(hashCode

通俗的說就是如果兩個對象通過equals() 方法比較得到的結果是相等的,那麼這兩個對象的hashCode 就一定是相等的。

如果我們重寫了一個對象的equals() 方法的時候沒有重寫其相應的hashCode() 方法,就會違反這一約定,如下的測試代碼

package com.blog.effective.note9;

/**
 * 〈一個簡單的電話號碼類〉<br>
 *
 * @author 未緒
 * @time 2018/1/2 15:50
 */
public class PhoneNumber {

    private static String phoneNumber;       //電話號碼
    private static String numAddr;          //電話號碼的歸屬地

    public PhoneNumber(String phoneNumber,String numAddr){
        this.phoneNumber=phoneNumber;
        this.numAddr=numAddr;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof PhoneNumber){
            PhoneNumber phoneNumber=(PhoneNumber)obj;
            return this.phoneNumber==phoneNumber.phoneNumber&&this.numAddr==phoneNumber.numAddr;
        }
        return false;
    }
}

如上是一個簡單的有段電話號碼類,其中包含號碼(phoneNumber)和歸屬地(numAddr)兩個屬性,並且我們重寫了它的equals() 方法

我們來測試一下

    public static void main(String[] args) {

        PhoneNumber phoneNumber1 = new PhoneNumber("123", "FZ");
        PhoneNumber phoneNumber2 = new PhoneNumber("123", "FZ");

        System.out.println(phoneNumber1.hashCode());        //621009875
        System.out.println(phoneNumber2.hashCode());        //1265094477

        System.out.println(phoneNumber1.equals(phoneNumber2));//true

    }

看到輸出就知道這是違反了開始所說的Object 類的通用約定。

那麼如果就像上面這樣寫會有什麼危害呢?—— 無法與所有的基於散列的集合一起正常使用

如下我們要實現一個根據電話號碼來查詢相關的用戶的功能

        HashMap<PhoneNumber, String> hashMap = new HashMap<>();

        PhoneNumber number = new PhoneNumber("123", "FZ");
        hashMap.put(number,"張三");

        hashMap.get(new PhoneNumber("123","FZ"));

按照道理來說我們期望的返回結果是張三,然而實際運行的結果確實null
這就是因爲這兩者的hashCode 是不相同的,所以從基於散列的集合中查詢不到數據。

所以我們就要根據當前類的屬性值來生成其對應的hashCode ,確保當equals() 方法返回的爲true 的情況下,其散列值也相同。

有關如何簡單的生成一個這樣的散列值,將在下一篇博客中說明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章