蔚來(lái)一面:用Object做hashMap的Key時(shí)需要做什么?

作者 | petterp
先來(lái)說(shuō)一下hashcode()和equals方法吧。
hashcode()
hashCode 的存在主要用于查找的快捷性,如 Hashtable, HashMap 等,hashCode 是用來(lái)在三列存儲(chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的。 如果兩個(gè)對(duì)象相同,就是適用于 euqals(java.lang.Object) 方法,那么這兩個(gè)對(duì)象的 hashCode一定相同。 如果對(duì)象的euqals 方法被重寫(xiě),那么對(duì)象的 hashCode 也盡量重寫(xiě),并且產(chǎn)生 hashCode 使用的對(duì)象,一定要和 equals 方法中使用的一致,否則就會(huì)違反上面提到的第二點(diǎn)。 兩個(gè)對(duì)象的 hashCode 相同,并不一定表示這兩個(gè)對(duì)象就相同,也就是不一定適用于equals() 方法,只能夠說(shuō)明這兩個(gè)對(duì)象在三列存儲(chǔ)結(jié)構(gòu)中,如 Hashtable.,他們存在同一個(gè)籃子里。以上話以前摘錄自一篇博客,講的非常好。
equals(Object obj)
如果一個(gè)類(lèi)沒(méi)有重寫(xiě) equals(Object obj)方法,則等價(jià)于通過(guò) == 比較兩個(gè)對(duì)象,即比較的是對(duì)象在內(nèi)存中的空間地址是否相等。 如果重寫(xiě)了equals(Object ibj)方法,則根據(jù)重寫(xiě)的方法內(nèi)容去比較相等,返回 true 則相等,false 則不相等。
我用一個(gè)簡(jiǎn)單的demo來(lái)舉個(gè)例子吧.
public class MyClass {
public static void main(String[] args) {
HashSet books=new HashSet();
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
}
}
class A{
//類(lèi)A的 equals 方法總是返回true,但沒(méi)有重寫(xiě)其hashCode() 方法
@Override
public boolean equals(Object o) {
return true;
}
}
class B{
//類(lèi)B 的hashCode() 方法總是返回1,但沒(méi)有重寫(xiě)其equals()方法
@Override
public int hashCode() {
return 1;
}
}
class C{
public int hashCode(){
return 2;
}
@Override
public boolean equals(Object o) {
return true;
}
}
結(jié)果
即使兩個(gè)A 對(duì)象通過(guò) equals() 比較返回true,但HashSet 依然把他們當(dāng)成 兩個(gè)對(duì)象,即使兩個(gè) B 對(duì)象 的hashCode() 返回值相同,但HashSet 依然把他們當(dāng)成兩個(gè)對(duì)象。 即也就是,當(dāng)把一個(gè)對(duì)象放入HashSet 中時(shí),如果需要重寫(xiě)該對(duì)象對(duì)應(yīng)類(lèi)的 equals() 方法,則也應(yīng)該重寫(xiě)其 hashCode() 方法。規(guī)則是:如果兩個(gè)對(duì)象通過(guò) equals() 方法比較返回true,這兩個(gè)對(duì)象的 hashCode 值也應(yīng)該相同。 如果兩個(gè)對(duì)象通過(guò)euqals() 方法比較返回true,但這兩個(gè)對(duì)象的 hashCode() 方法返回不同的hashCode 值時(shí),這將導(dǎo)致HashSet 會(huì)把這兩個(gè)對(duì)象保存在 Hash 表的不同位置,從而使兩個(gè)對(duì)象都可以添加成功,這就與 Set 集合的規(guī)則沖突了。 如果兩個(gè)對(duì)象的 hashCode() 方法返回的 hasCode 值相同,但他們通過(guò) equals() 方法比較返回false 時(shí)將更麻煩:因?yàn)閮蓚€(gè)對(duì)象的hashCode 值相同,HashSet 將試圖 把它們保存在同一個(gè)位置,但又不行(否則將只剩下一個(gè)對(duì)象),所以實(shí)際上會(huì)在這個(gè)位置用鏈?zhǔn)浇Y(jié)構(gòu)來(lái)保存多個(gè)對(duì)象;而HashSet 訪問(wèn)集合元素時(shí)也是根據(jù)元素的 hashCode 值來(lái)快速定位的,如果 hashSet 中兩個(gè)以上的元素具有相同的 HashCode 值時(shí),將會(huì)導(dǎo)致性能下降。
用Object做hashMap的Key時(shí)需要做什么?
用自定義類(lèi)作為key,必須重寫(xiě)equals()和hashCode()方法。
自定義類(lèi)中的equals() 和 hashCode()都繼承自O(shè)bject類(lèi)。
程序汪資料鏈接
程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理
Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 04版
堪稱(chēng)神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門(mén)到實(shí)戰(zhàn)進(jìn)階
臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!
臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!
字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!
歡迎添加程序汪個(gè)人微信 itwang007 進(jìn)粉絲群或圍觀朋友圈
評(píng)論
圖片
表情
