equal、hashcode、==
1、==
java中的數(shù)據(jù)類型,可分為兩類:
1.基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型
byte,short,char,int,long,float,double,boolean ? 他們之間
?
的比較,應(yīng)用雙等號(hào)(==),比較的是他們的值。?
2.引用類型(類、接口、數(shù)組) ??
當(dāng)他們用(==)進(jìn)行比較的時(shí)候,比較的是他們?cè)趦?nèi)存中的存放地址,所以,除非是同一個(gè)new出來的對(duì)象,他們的比較后的結(jié)果為true,否則比較后結(jié)果為false。
對(duì)象是放在堆中的,棧中存放的是對(duì)象的引用(地址)。由此可見'=='是對(duì)棧中的值進(jìn)行比較的。如果要比較堆中對(duì)象的內(nèi)容是否相同,那么就要重寫equals方法了。
2、equals
1、默認(rèn)情況(沒有覆蓋equals方法)下equals方法都是調(diào)用Object類的equals方法,而Object的equals方法主要用于判斷對(duì)象的內(nèi)存地址引用是不是同一個(gè)地址(是不是同一個(gè)對(duì)象)。定義的equals與==是等效的
2.要是類中覆蓋了equals方法,那么就要根據(jù)具體的代碼來確定equals方法的作用了,覆蓋后一般都是通過對(duì)象的內(nèi)容是否相等來判斷對(duì)象是否相等。
3.hashCode的作用
?
hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實(shí)際上是返回一個(gè)int整數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。
hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)。
? ? ? ? 雖然,每個(gè)Java類都包含hashCode() 函數(shù)。但是,僅僅當(dāng)創(chuàng)建某個(gè)“類的散列表”(關(guān)于“散列表”見下面說明)時(shí),該類的hashCode() 才有用(作用是:確定該類的每一個(gè)對(duì)象在散列表中的位置;其它情況下(例如,創(chuàng)建類的單個(gè)對(duì)象,或者創(chuàng)建類的對(duì)象數(shù)組等等),類的hashCode() 沒有作用。
? ? ? ?上面的散列表,指的是:Java集合中本質(zhì)是散列表的類,如HashMap,Hashtable,HashSet。
? ? ? ?也就是說:hashCode() 在散列表中才有用,在其它情況下沒用。在散列表中hashCode() 的作用是獲取對(duì)象的散列碼,進(jìn)而確定該對(duì)象在散列表中的位置。
OK!至此,我們搞清楚了:hashCode()的作用是獲取散列碼。
?
equal和hashcode的關(guān)系
1、如果兩個(gè)對(duì)象equals,Java運(yùn)行時(shí)環(huán)境會(huì)認(rèn)為他們的hashcode一定相等。?
2、如果兩個(gè)對(duì)象不equals,他們的hashcode有可能相等。?
3、如果兩個(gè)對(duì)象hashcode相等,他們不一定equals。?
4、如果兩個(gè)對(duì)象hashcode不相等,他們一定不equals。?
關(guān)于這兩個(gè)方法的重要規(guī)范:?
規(guī)范1:若重寫equals(Object obj)方法,有必要重寫hashcode()方法,確保通過equals(Object obj)方法判斷結(jié)果為true的兩個(gè)對(duì)象具備相等的hashcode()返回值。說得簡單點(diǎn)就是:“如果兩個(gè)對(duì)象相同,那么他們的hashcode應(yīng)該相等”。不過請(qǐng)注意:這個(gè)只是規(guī)范,如果你非要寫一個(gè)類讓equals(Object obj)返回true而hashcode()返回兩個(gè)不相等的值,編譯和運(yùn)行都是不會(huì)報(bào)錯(cuò)的。不過這樣違反了Java規(guī)范,程序也就埋下了BUG。?
規(guī)范2:如果equals(Object obj)返回false,即兩個(gè)對(duì)象“不相同”,并不要求對(duì)這兩個(gè)對(duì)象調(diào)用hashcode()方法得到兩個(gè)不相同的數(shù)。說的簡單點(diǎn)就是:“如果兩個(gè)對(duì)象不相同,他們的hashcode可能相同”。?
為什么覆蓋equals時(shí)總要覆蓋hashCode?
?一個(gè)很常見的錯(cuò)誤根源在于沒有覆蓋hashCode方法。在每個(gè)覆蓋了equals方法的類中,也必須覆蓋hashCode方法。如果不這樣做的話,就會(huì)違反Object.hashCode的通用約定,從而導(dǎo)致該類無法結(jié)合所有基于散列的集合一起正常運(yùn)作,這樣的集合包括HashMap、HashSet和Hashtable。
1.在應(yīng)用程序的執(zhí)行期間,只要對(duì)象的equals方法的比較操作所用到的信息沒有被修改,那么對(duì)這同一個(gè)對(duì)象調(diào)用多次,hashCode方法都必須始終如一地返回同一個(gè)整數(shù)。在同一個(gè)應(yīng)用程序的多次執(zhí)行過程中,每次執(zhí)行所返回的整數(shù)可以不一致。
2.如果兩個(gè)對(duì)象根據(jù)equals()方法比較是相等的,那么調(diào)用這兩個(gè)對(duì)象中任意一個(gè)對(duì)象的hashCode方法都必須產(chǎn)生同樣的整數(shù)結(jié)果。
3.如果兩個(gè)對(duì)象根據(jù)equals()方法比較是不相等的,那么調(diào)用這兩個(gè)對(duì)象中任意一個(gè)對(duì)象的hashCode方法,則不一定要產(chǎn)生相同的整數(shù)結(jié)果。但是程序員應(yīng)該知道,給不相等的對(duì)象產(chǎn)生截然不同的整數(shù)結(jié)果,有可能提高散列表的性能。
?
總結(jié)
以上是生活随笔為你收集整理的equal、hashcode、==的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java集合:ArrayList和Lin
- 下一篇: Redis: 跳跃表