- Java程序員面試筆試寶典(第2版)
- 何昊等編著
- 1541字
- 2022-06-17 16:00:50
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方法的返回值則可能相等,也可能不等。
- 自然語言處理實戰(zhàn):預(yù)訓(xùn)練模型應(yīng)用及其產(chǎn)品化
- Python量化投資指南:基礎(chǔ)、數(shù)據(jù)與實戰(zhàn)
- Android Development with Kotlin
- Getting Started with Python Data Analysis
- Java編程技術(shù)與項目實戰(zhàn)(第2版)
- C#程序設(shè)計
- bbPress Complete
- 焊接機器人系統(tǒng)操作、編程與維護
- C語言程序設(shè)計上機指導(dǎo)與習(xí)題解答(第2版)
- 第一行代碼 C語言(視頻講解版)
- RubyMotion iOS Develoment Essentials
- JQuery風(fēng)暴:完美用戶體驗
- Qt 4開發(fā)實踐
- 例說FPGA:可直接用于工程項目的第一手經(jīng)驗
- 一步一步學(xué)Spring Boot:微服務(wù)項目實戰(zhàn)(第2版)