1. 程式人生 > >淺談hashcode()和equals()方法

淺談hashcode()和equals()方法

Java Object 類中存在hashcode()方法以及equals方法

public native int hashCode();
public boolean equals(Object obj) {

    return (this == obj);

}

hashCode方法是一個本地方法用於獲取一個對像的hash值,equals方法用於比較兩個物件的地址是否相等。

我們判斷一個物件相等的條件是:

兩個物件的hash值相等且equals方法返回ture.

例如String類重寫了equals方法,用於比較內容。

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }

    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

從程式碼可以看出,如果物件地址相同直接返回true,否則比較內容,如果內容相同則返回true否則返回false.

在沒有重寫equals方法前加入有兩個物件 str1 str2 ,兩者的hash值大概率是不相等的,equals 也是不等的,重寫後equals相等,那麼hash值也應相等,所以要重新寫hashcode(),利用字串的每一位做hash那麼兩個內容相同的字串hash必定相同。

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

在Java API文件中關於hashCode方法有以下幾點規定:

1 在java應用程式執行期間,如果在equals方法比較中所用的資訊沒有被修改,那麼在同一個物件上多次呼叫hashCode方法時必須一致地返回相同的整數。如果多次執行同一個應用時,不要求該整數必須相同。

2 如果兩個物件通過呼叫equals方法是相等的,那麼這兩個物件呼叫hashCode方法必須返回相同的整數。

3. 如果兩個物件通過呼叫equals方法是不相等的,不要求這兩個物件呼叫hashCode方法必須返回不同的整數。但是程式設計師應該意識到對不同的物件產生不同的hash值可以提供雜湊表的效能。

應用於map型別的資料結構時特別明顯:

Map中的key值是根據hashcode實現的,eg,set集合,如果重寫了equals方法,如String類,如果不重寫hashcode()則可能會存入兩個相同的字串,這和set的集合特性不一致。