Java中的equals方法與hashCode方法解析


我們都知道Java語言是完全面向對象的,在java中,所有的對象都是繼承於Object類。Ojbect類中有兩個方法equalshashCode,這兩個方法都是用來比較兩個對象是否相等的。

java中比較兩個對象不是用“==”嗎?對於String a=”hello”;String b=”hello”,比較兩個字符串是否相等,我們都知道必須用equals方法,而不是用==。 因爲ab是內存中兩個不同的對象,他們指向兩個內存中不同的地址,只是兩個地址存的內容都相同罷了。如果用==比較,則比較的是兩個對象的地址,很顯然這裏返回false,不是我們需要的。如果想返回true,就必須使用equals方法了。在這裏String類裏對父類Ojbectequals方法進行了重寫(見String類裏的equals方法),比較的不再是地址,而是地址裏所存的字符串的值。如果不對equals方法重寫,調用的就是父類的equals方法,比較的還是兩個對象的地址,同調用==一樣。

對於值對象,==比較的是兩個對象的值,對於引用對象,比較的是兩個對象的地址。默認的equals方法同==,一般來說我們的對象都是引用對象,要重寫equals方法。再舉一個例子,現在有一個學生對象,有屬性學號跟姓名,現在我新建了一個學生對象,又從數據裏查出一個學生對象,這兩個對象的學號跟姓名都一樣,那這兩個對象是不是相等呢?一般情況下,除非你有特殊需求要處理,這兩個對象是相等的,可如果用==去比較,返回的結果是錯誤的。這時候我們就必須重寫equlas方法了。如果學號是主鍵,在equals方法裏,我們認爲只要學號相同,就可以返回true,具體實現建議參考String類裏equals書寫風格。

hashCode方法也是可以用來比較兩個對象是否相等的。但是我們很少使用,應該說是很少直接使用。hashCode方法返回的是一個int值,可以看做是一個對象的唯一編碼,如果兩個對象的hashCode值相同,我們應該認爲這兩個對象是同一個對象。一般如果使用java中的Map對象進行存儲時,他會自動調用hashCode方法來比較兩個對象是否相等。所以如果我們對equals方法進行了重寫,建議一定要對hashCode方法重寫,以保證相同的對象返回相同的hash值,不同的對象返回不同的hash值。如上面的學生例子,如果學號相同,不管姓名相不相同,返回的hash值一定要是一樣的,這時我們的hash值只與學號有關。

String類中的equals方法 與hashCode方法:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = count;
            if (n == anotherString.count) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = offset;
                int j = anotherString.offset;
                while (n-- != 0) {
                    if (v1[i++] != v2[j++])
                        return false;
                }
                return true;
            }
        }
        return false;
    }

public int hashCode() {
        int h = hash;
        if (h == 0) {
            int off = offset;
            char val[] = value;
            int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
	}

查閱百度知道的信息:

hash從意義上來說應該是實現值的比較。

hashCode值與對象引用沒有必然聯繫。在java中,值相同的兩個字符串不一定是同個對象。比如你上面的ab就是兩個不同的對象。

字符串的hash值是根據字符串的值計算的,相同值的字符串對象hash值一定相同,具體的計算方法在jdk的文檔中有描述.

每個java對象都有一個唯一的標識,object類中的hash方法就是直接返回對象的這個內部id號,與stringhash方法是不同的,objecthash方法能夠用來區分不同的對象.因爲原始的object對象沒有任何有意義的值可用來計算哈希。


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