1. 程式人生 > >"=="、equals和hashCode有什麼區別

"=="、equals和hashCode有什麼區別

1)“==”運算子用來比較兩個變數的值是否相等。也就是說,該運算子用於比較變數對應的記憶體中所儲存的數值是否相同,要比較兩個基本型別的資料或兩個引用變數是否相等,只能使用“==”運算子。

具體而言,如果兩個變數是基本資料型別,可以直接使用“==”運算子來比較其對應的值是否相等。如果一個變數指向的資料是物件(引用型別),那麼,此時涉及了兩塊記憶體,物件本身佔用了一塊記憶體(堆記憶體),變數也佔用一塊記憶體,例如,對於賦值語句:

String s = new String();
變數s佔用一塊儲存空間,而new String()則儲存在另外一塊儲存空間裡,此時,變數s所對應記憶體中儲存的數值就是物件佔用的那塊記憶體的首地址。對於指向物件型別的變數,如果要比較兩個變數是否指向同一個物件,即要看這兩個變數所對應的記憶體中的數值是否相等(這兩個物件是否指向同一塊儲存空間),這時候就可以用“==”運算子進行比較。但是,如果要比較這兩個物件的內容是否相等,那麼用“==”運算子就無法實現了。

2)equals是Object類提供的方法之一。每一個Java類都整合自Object類,所以每一個物件都具有equals這個方法。Object類中定義的equals(Object)方法的情況下,equals(Object)與“==”運算子一樣,比較的是引用。

相比“==”運算子,equals(Object)方法的特殊之處就在於它可以被覆蓋,所以可以通過覆蓋的方法讓它不是比較引用而是比較資料內容,例如String類的equals方法是用於比較兩個獨立物件的內容是否相同,即堆中的內容是否相同,以下面的程式碼為例:

String s1 = new String("Hello");
		String s2 = new String("Hello");
兩條new語句建立了兩個物件,然後用s1、s2這兩個變數分別指向一個物件,這是兩個不同的物件,它們的首地址是不同的,即s1和s2中儲存的數值是不相同的,所以,表示式s1==s2將返回false,而這兩個物件中的內容是相同的,所以,表示式s1.equals(s2)將返回true。

如果一個類沒有自己定義equals()方法,那麼它將繼承Object類的equals()方法,Object類的equals()方法的實現程式碼如下:

boolean equals(Object object){
		return this==object;
	}
通過以上例子可以說明,如果一個類沒有自己定義equals()方法,它預設的equals()方法(從Object類繼承的)就是使用“==”運算子,也是在比較兩個變數指向的物件是否是同一物件,此時使用equals()方法和使用“==”運算子會得到同樣的結果。若比較的是兩個獨立的物件,則總返回false。如果編寫的類希望能夠比較該類建立的兩個例項物件的內容是否相同,那麼必須覆蓋equals()方法,由開發人員自己編寫程式碼來決定在什麼情況下即可認為兩個物件的內容是相同的。

3)hashCode()方法是從Object類中繼承過來的,它也用來鑑定兩個物件是否相等。Object類中的hashCode()方法返回物件在記憶體中地址轉換成的一個int值,所以如果沒有重寫hashCode()方法,任何物件的hashCode()方法都是不相等的。

雖然equals()方法也是用來判斷兩個物件是否相等的,但是它與hashCode()方法是有區別的。一般來講,equals()方法是給使用者呼叫的,如果需要判斷兩個物件是否相等的,可以重寫equals()方法,然後在程式碼中呼叫,這樣就可以判斷它們是否相等了。對於hashCode()方法,使用者一般不會去呼叫它,例如在hashmap中,由於key是不可以重複的,它在判斷key是否重複時就判斷了hashCode()方法,而且也用到了equals()方法。此處“不可以重複”指的是equals()和hashCode()只要有一個不等就可以了。所以,hashCode()方法相當於是一個物件的編碼,就好像檔案中的md5,它與equals()方法的不同之處就在於它返回的是int型,比較起來不直觀。

一般在覆蓋equals()方法的同時也要覆蓋hashCode()方法,否則,就會違反Object.hashCode的通用約定,從而導致該類無法與所有基於雜湊值(hash)集合類(HashMap、HashSet和Hashtable)結合在一起正常執行。

hashCode()方法的返回值和equals()方法的關係如下:

x.equals(y)返回true,即兩個物件根據equals()方法比較是相等的,那麼呼叫這兩個物件中任意一個物件的hashCode()方法都必須產生同樣的整數結果。如果x.equals(y)返回false,即兩個物件根據equals()方法比較是不相等的,那麼x和y的hashCode()方法的返回值有可能相等,也有可能不相等。反之,hashCode()方法的返回值不相等,一定能推出equals()方法的返回值也不相等,而hashCode()方法的返回值相等,equals()方法的返回值則可能相等,也可能不相等。