蔚來(lái)一面:用Object做hashMap的Key時(shí)需要做什么?
閱讀本文大概需要 2.8 分鐘。
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è)籃子里。以上話(huà)以前摘錄自一篇博客,講的非常好。
equals(Object obj)
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;
?}
}
即使兩個(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 訪(fǎng)問(wèn)集合元素時(shí)也是根據(jù)元素的 hashCode 值來(lái)快速定位的,如果 hashSet 中兩個(gè)以上的元素具有相同的 HashCode 值時(shí),將會(huì)導(dǎo)致性能下降。
推薦閱讀:
SpringBoot + Kafka + ELK 完成海量日志收集(超詳細(xì))
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
朕已閱?

