重寫equals()與hashCode()方法


出自:http://blog.csdn.net/renfufei/article/details/16339351

Java語言是完全面向對象的,在java中,所有的對象都是繼承於Object類。Ojbect類中有兩個方法equals、hashCode,這兩個方法都是用來比較兩個對象是否相等的。在沒有重寫equals方法我們是繼承了object的equals方法,那里的 equals是比較兩個對象的內存地址,顯然我們new了2個對象內存地址肯定不一樣。

對於基本數據類型,==比較的是兩個變量的值。對於引用對象,==比較的是兩個對象的地址。默認的equals方法等同==,一般來說我們的對象都是引用對象,要重寫equals方法。

對equals方法進行了重寫,建議一定要對hashCode方法重寫,以保證相同的對象返回相同的hash值,不同的對象返回不同的hash值。

1. 錯誤使用方式
下面是一個常見的錯誤用法:

 

import java.util.HashMap;


public class Apple {
    private String color;

    public Apple(String color) {
        this.color = color;
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof Apple)) {
            return false;
        }

        if (obj == this) {
            return true;
        }

        return this.color == ((Apple) obj).color;
    }

    public static void main(String[] args) {
        Apple a1 = new Apple("green");
        Apple a2 = new Apple("red");

        //hashMap stores apple type and its quantity
        HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Apple("green")));
    }
}

在此示例中,hashMap 已經保存了一個綠色的Apple對象,但想(通過程序中的方式)從map獲取此對象時,apple 對象並未被找到.
上述代碼的輸出結果是: null. 但通過斷點調試,可以確定此對象已經存在於hashMap中,截圖如下:

2. 此問題由hashCode()引起
問題的原因是沒有重寫"hashCode()"方法.
equals()方法與hashCode()的通用協定是:
2.1 如果兩個對象相等(equal),那么必須擁有相同的哈希碼(hash code)
2.2 即使兩個對象有相同的哈希值(hash code),他們不一定相等.

Map的核心思想就是可以比線性查找更快. 通過散列值(hash)作為鍵(key)來定位對象的過程分為兩步:
在Map內部,存儲着一個頂層數組,頂層數組的每個元素指向其他的數組,查找或存儲的時候,先根據key對象的hashCode()值計算出數組的索引,然后到這個索引找到所指向的第二層線性數組,使用equals方法來比較是否有相應的值(以返回或者存儲).
Object類中的hashCode()默認為每個對象返回不同的int值,因此在上面的例子中,兩個相等(equal)的對象,返回了不同的hashCode值.
解決方法是為此類添加hashCode方法,比如,使用color字符串的長度作為示范:

public int hashCode(){ 
   //此種實現,要求 color值定以后就不得修改
   //否則同一個物理對象,前后有兩個不同的hashCode,邏輯上就是錯的
   return this.color.length();   
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM