HashSet要求不能存儲(chǔ)相同的對(duì)象,HashMap要求不能存儲(chǔ)相同的鍵。
JDK對(duì)equals(Object obj)和hashcode()這兩個(gè)方法的定義和規(guī)范: 在Java中任何一個(gè)對(duì)象都具備equals(Object obj)和hashcode()這兩個(gè)方法凉敲,因?yàn)樗麄兪窃贠bject類中定義的玫鸟。equals(Object obj)方法用來(lái)判斷兩個(gè)對(duì)象是否“相同”占锯,如果“相同”則返回true,否則返回false韵丑。 hashcode()方法返回一個(gè)int數(shù),在Object類中的默認(rèn)實(shí)現(xiàn)是“將該對(duì)象的內(nèi)部地址轉(zhuǎn)換成一個(gè)整數(shù)返回”虚缎。
兩個(gè)最重要的重要規(guī)范(不止兩個(gè)):?
規(guī)范1:若重寫equals(Object obj)方法撵彻,有必要重寫hashcode()方法,確保通過(guò)equals(Object obj)方法判斷結(jié)果為true的兩個(gè)對(duì)象具備相等的hashcode()返回值实牡。說(shuō)得簡(jiǎn)單點(diǎn)就是:“如果兩個(gè)對(duì)象相同陌僵,那么他們的hashcode應(yīng)該相等”。不過(guò)請(qǐng)注意:這個(gè)只是規(guī)范创坞,如果你非要寫一個(gè)類讓equals(Object obj)返回true而hashcode()返回兩個(gè)不相等的值碗短,編譯和運(yùn)行都是不會(huì)報(bào)錯(cuò)的。不過(guò)這樣違反了Java規(guī)范题涨,程序也就埋下了BUG偎谁。
規(guī)范2:如果equals(Object obj)返回false总滩,即兩個(gè)對(duì)象“不相同”,并不要求對(duì)這兩個(gè)對(duì)象調(diào)用hashcode()方法得到兩個(gè)不相同的數(shù)巡雨。說(shuō)的簡(jiǎn)單點(diǎn)就是:“如果兩個(gè)對(duì)象不相同闰渔,他們的hashcode可能相同”。
根據(jù)這兩個(gè)規(guī)范铐望,可以得到如下推論: (充分不必要)
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虱痕。?
java運(yùn)行時(shí)環(huán)境是怎樣判斷HashSet和HastMap中的兩個(gè)對(duì)象相同或不同了:先判斷hashcode是否相等睹耐,再判斷是否equals。?
參考:https://www.cnblogs.com/xiohao/p/4199446.html
Object類定義中對(duì)hashCode和equals要求如下:
1)如果兩個(gè)對(duì)象的equals的結(jié)果是相等的部翘,則兩個(gè)對(duì)象的hashCode的返回結(jié)果也必須是相同的硝训。
2)任何時(shí)候覆寫equals,都必須同時(shí)覆寫hashCode新思。
參考《碼出高效》P177
1.equals和==
1)==用于比較引用和比較基本數(shù)據(jù)類型時(shí)具有不同的功能:
比較基本數(shù)據(jù)類型窖梁,如果兩個(gè)值相同,則結(jié)果為true
比較引用時(shí)夹囚,如果引用指向內(nèi)存中的同一對(duì)象纵刘,結(jié)果為true;
2)equals()作為方法,實(shí)現(xiàn)對(duì)象的比較荸哟。由于==運(yùn)算符不允許我們進(jìn)行覆蓋假哎,也就是說(shuō)它限制了我們的表達(dá)。因此我們復(fù)寫equals()方法鞍历,達(dá)到比較對(duì)象內(nèi)容是否相同的目的舵抹。而這些通過(guò)==運(yùn)算符是做不到的。
2.object類的equals()方法的比較規(guī)則為:如果兩個(gè)對(duì)象的類型一致堰燎,并且內(nèi)容一致掏父,則返回true,這些類有:
java.io.file,java.util.Date,java.lang.string,包裝類(Integer,Double等)
String s1=new String("abc");
String s2=new String("abc");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
運(yùn)行結(jié)果為false true。