官术网_书友最值得收藏!

1.17 “==”、equals和hashCode的區(qū)別

1)“==”運算符用來比較兩個變量的值是否相等,也就是用于比較變量所對應(yīng)的內(nèi)存中存儲的數(shù)值是否相同,要比較兩個基本類型的數(shù)據(jù)或兩個引用變量是否相等,只能用“==”運算符。

具體而言,如果兩個變量是基本數(shù)據(jù)類型,可以直接用“==”來比較其對應(yīng)的值是否相等。如果一個變量指向的數(shù)據(jù)是對象(引用類型),那么,此時涉及了兩塊內(nèi)存,對象本身占用一塊內(nèi)存(堆內(nèi)存),對象的引用也占用一塊內(nèi)存。例如,對于賦值語句String s=new String(),變量s占用一塊存儲空間(一般在棧中),而new String()則存儲在另外一塊存儲空間里(一般在堆中),此時,變量s所對應(yīng)的內(nèi)存中存儲的數(shù)值就是對象占用的那塊內(nèi)存的首地址。對于指向?qū)ο箢愋偷淖兞浚绻容^兩個變量是否指向同一個對象,即要看這兩個變量所對應(yīng)的內(nèi)存中的數(shù)值是否相等(這兩個對象是否指向同一塊存儲空間),這時候就可以用“==”運算符進行比較。但是,如果要比較這兩個對象的內(nèi)容是否相等,那么用“==”運算符就無法實現(xiàn)了。

2)equals是Object類提供的方法之一,每一個Java類都繼承自O(shè)bject類,所以每一個對象都具有equals這個方法。Object類中定義的equals(Object)方法是直接使用“==”比較的兩個對象,所以在沒有覆蓋equals(Object)方法的情況下,equals(Object)與“==”一樣,比較的是引用。

相比“==”運算符,equals(Object)方法的特殊之處就在于它可以被覆蓋,所以可以通過覆蓋這個方法讓它不是比較引用而是比較對象的屬性。例如String類的equals方法是用于比較兩個獨立對象的內(nèi)容是否相同,即堆中的內(nèi)容是否相同。例如,對于下面的代碼:

兩條new語句在堆中創(chuàng)建了兩個對象,然后用s1、s2這兩個變量分別指向這兩個對象,這是兩個不同的對象,它們的首地址是不同的,即s1和s2中存儲的數(shù)值是不相同的,所以,表達式a==b將返回false,而這兩個對象中的內(nèi)容是相同的,所以,表達式a.equals(b)將返回true。

如果一個類沒有實現(xiàn)equals方法,那么它將繼承Object類的equals方法,Object類的equals方法的實現(xiàn)代碼如下:

通過以上例子可以說明,如果一個類沒有自己定義equals方法,它默認的equals方法(從Object類繼承的)就是使用“==”運算符,也就是在比較兩個變量指向的對象是否是同一對象,此時使用equals方法和使用“==”會得到同樣的結(jié)果,如果比較的是兩個獨立的對象則總返回false。如果編寫的類希望能夠比較該類創(chuàng)建的兩個實例對象的內(nèi)容是否相同,那么必須覆蓋equals方法,由開發(fā)人員自己寫代碼來決定在什么情況下即可認為兩個對象的內(nèi)容是相同的。

3)hashCode()方法是從Object類中繼承過來的,它也用來鑒定兩個對象是否相等。Object類中的hashCode()方法返回對象在內(nèi)存中地址轉(zhuǎn)換成的一個int值,所以如果沒有重寫hashCode()方法,任何對象的hashCode()方法都是不相等的。

雖然equals方法也是用來判斷兩個對象是否相等的,但是二者是有區(qū)別的。一般來講,equals方法是給用戶調(diào)用的,如果需要判斷兩個對象是否相等,可以重寫equals方法,然后在代碼中調(diào)用,就可以判斷它們是否相等了。對于hashCode()方法,用戶一般不會去調(diào)用它,例如在HashMap中,由于key是不可以重復(fù)的,它在判斷key是否重復(fù)的時候就判斷了hashCode()這個方法,而且也用到了equals方法。此處“不可以重復(fù)”指的是equals和hashCode()只要有一個不等就可以了。所以,hashCode()相當(dāng)于是一個對象的編碼,就好像文件中的md5,它與equals方法的不同之處就在于它返回的是int型,比較起來不直觀。

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

hashCode()的返回值和equals方法的關(guān)系如下:如果x.equals(y)返回true,即兩個對象根據(jù)equals方法比較是相等的,那么調(diào)用這兩個對象中任意一個對象的hashCode()方法都必須產(chǎn)生同樣的整數(shù)結(jié)果。如果x.equals(y)返回false,即兩個對象根據(jù)equals()方法比較是不相等的,那么x和y的hashCode()方法的返回值有可能相等,也有可能不等。反過來,hashCode()方法的返回值不等,一定能推出equals方法的返回值也不等,而hashCode()方法的返回值相等,equals方法的返回值則可能相等,也可能不等。

主站蜘蛛池模板: 新建县| 三明市| 长白| 南郑县| 武清区| 台州市| 吉水县| 白玉县| 锡林浩特市| 阿瓦提县| 兴和县| 台南市| 苏尼特右旗| 延长县| 安新县| 东台市| 闽侯县| 白山市| 赤峰市| 辽宁省| 灵寿县| 和硕县| 阿坝县| 若羌县| 简阳市| 芜湖市| 甘德县| 巧家县| 咸宁市| 鸡西市| 兴仁县| 青岛市| 吉木萨尔县| 林州市| 龙泉市| 庆城县| 乳山市| 奇台县| 孝昌县| 科技| 彭州市|