看似簡單的hashCode和equals面試題,竟然有這麼多坑!

在這裏插入圖片描述

作者:徐劉根,大家都喊我根哥!

hashCode()方法和equals()區別與聯繫這到面試題,看似簡單,根據以往面試星友的情況來說,絕大部分人都不能很好的回答出來,要麼沒有邏輯,想到一句就說一句,要麼抓不住重點,答非所問。從這個很小的面試題上我們就可以看出來,對於任何一個面試題來說,都是要清晰有條理的回答。那麼如何才能回答到點子上並且讓面試官覺得你的邏輯清晰哪?

首先,我們要介紹hashCode()和equals()方法的作用是是什麼,然後才說他的區別,說了區別之後再說使用的時候需要注意到的地方,這樣的回答思路基本是OK的,如果你在瞭解一些其他人不知道的那就更好了!下邊我們就開始介紹:

一、hashCode()和equals()是什麼?

hashCode()方法和equals()方法的作用其實一樣,在Java裏都是用來對比兩個對象是否相等一致。

二、hashCode()和equals()的區別

下邊從兩個角度介紹了他們的區別:一個是性能,一個是可靠性。他們之間的主要區別也基本體現在這裏。

1、equals()既然已經能實現對比的功能了,爲什麼還要hashCode()呢?

因爲重寫的equals()裏一般比較的比較全面比較複雜,這樣效率就比較低,而利用hashCode()進行對比,則只要生成一個hash值進行比較就可以了,效率很高。

2、hashCode()既然效率這麼高爲什麼還要equals()呢?

因爲hashCode()並不是完全可靠,有時候不同的對象他們生成的hashcode也會一樣(生成hash值得公式可能存在的問題),所以hashCode()只能說是大部分時候可靠,並不是絕對可靠,所以我們可以得出(PS:以下兩條結論是重點,很多人面試的時候都說不出來):

  • equals()相等的兩個對象他們的hashCode()肯定相等,也就是用equals()對比是絕對可靠的。

  • hashCode()相等的兩個對象他們的equals()不一定相等,也就是hashCode()不是絕對可靠的。

三、hashCode()和equals()使用的注意事項

1、對於需要大量並且快速的對比的話如果都用equals()去做顯然效率太低,所以解決方式是,每當需要對比的時候,首先用hashCode()去對比,如果hashCode()不一樣,則表示這兩個對象肯定不相等(也就是不必再用equals()去再對比了),如果hashCode()相同,此時再對比他們的equals(),如果equals()也相同,則表示這兩個對象是真的相同了,這樣既能大大提高了效率也保證了對比的絕對正確性!

在這裏插入圖片描述

2、這種大量的並且快速的對象對比一般使用的hash容器中,比如HashSet,HashMap,HashTable等等,比如HashSet裏要求對象不能重複,則他內部必然要對添加進去的每個對象進行對比,而他的對比規則就是像上面說的那樣,先hashCode(),如果hashCode()相同,再用equals()驗證,如果hashCode()都不同,則肯定不同,這樣對比的效率就很高了。

3、然而hashCode()和equals()一樣都是基本類Object裏的方法,而和equals()一樣,Object裏hashCode()裏面只是返回當前對象的地址,如果是這樣的話,那麼我們相同的一個類,new兩個對象,由於他們在內存裏的地址不同,則他們的hashCode()不同,所以這顯然不是我們想要的,所以我們必須重寫我們類的hashCode()方法,即一個類,在hashCode()裏面返回唯一的一個hash值,比如下面:

在這裏插入圖片描述

由於標識這個類的是他的內部的變量num和name,所以我們就根據他們返回一個hash值,作爲這個類的唯一hash值。

所以如果我們的對象要想放進hashSet,並且發揮hashSet的特性(即不包含一樣的對象),則我們就要重寫我們類的hashCode()和equals()方法了。像String,Integer等這種類內部都已經重寫了這兩個方法。

當然如果我們只是平時想對比兩個對象 是否一致,則只重寫一個equals(),然後利用equals()去對比也行的。

四、擴展

1、阿里巴巴開發規範明確規定:

在這裏插入圖片描述

  • 只要重寫 equals,就必須重寫 hashCode;

  • 因爲 Set 存儲的是不重複的對象,依據 hashCode 和 equals 進行判斷,所以 Set 存儲的對象必須重寫這兩個方法;

  • 如果自定義對象做爲 Map 的鍵,那麼必須重寫 hashCode 和 equals;

  • String 重寫了 hashCode 和 equals 方法,所以我們可以非常愉快地使用 String 對象作爲 key 來使用;

2、什麼時候需要重寫?

一般的地方不需要重載hashCode,只有當類需要放在HashTable、HashMap、HashSet等等hash結構的集合時纔會重載hashCode。

3、那麼爲什麼要重載hashCode呢?

如果你重寫了equals,比如說是基於對象的內容實現的,而保留hashCode的實現不變,那麼很可能某兩個對象明明是“相等”,而hashCode卻不一樣。

這樣,當你用其中的一個作爲鍵保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一個作爲鍵值去查找他們的時候,則根本找不到。

4、爲什麼equals()相等,hashCode就一定要相等,而hashCode相等,卻不要求equals相等?

  • 因爲是按照hashCode來訪問小內存塊,所以hashCode必須相等。

  • HashMap獲取一個對象是比較key的hashCode相等和equals爲true。

之所以hashCode相等,卻可以equal不等,就比如ObjectA和ObjectB他們都有屬性name,那麼hashCode都以name計算,所以hashCode一樣,但是兩個對象屬於不同類型,所以equals爲false。

5、爲什麼需要hashCode?

  • 通過hashCode可以很快的查到小內存塊。

  • 通過hashCode比較比equals方法快,當get時先比較hashCode,如果hashCode不同,直接返回false。

五、總結

從上邊一道簡單的面試題我們可以擴展到其他面試題的回答上,首先你要對這個東西明白,然後纔能有條理,清晰的給面試官介紹你掌握的內容,描述的過程也是很重要的,不能毫無章法,要遊刃有餘。這一點相信是很多面試者最吃虧的地方,自己明白的東西都講不清楚,沒有條理!

面試的時候,我們的理想境界大概就是“會的東西你能夠講明白,讓面試官覺得你對這個東西很有研究;不會的東西你能夠說出來,讓面試官覺得你對這個東西有了解”!爲了這個目標,2019年春節過後,我已經給自己立了一個flag,每天有條理、清晰的整理一道面試題,分享到自己的知識星球裏邊,和大家一起學習交流,幫助大家養成良好的面試問題回答習慣,希望能夠靠自己的一點經驗給大家帶來力所能及的幫助。以上關於hashCode和equals常見的面試題和回答思路也是其中已經整理出來的一道題目。

截至目前,過去的一個多月的時間,已經陸續整理出來了30多道高頻的面試題,以往知識星球幾乎沒有宣傳過,2019年誠邀大家一起學習和交流,最近還有一段時間的優惠,有興趣的可以看一下。(微信掃碼即可查看)

在這裏插入圖片描述

本系列面試題常年更新,拒絕網上的直接搬運,網上大量的其他平臺,看似幾百道,幾千到面試題,但大都是網上搜集的答案,自己只顧着收錢,都不會認真的看一下題目。一方面,正確性有待考量;另一方面,單個知識點毫無關聯!使得讀者只知其一,不知其二,最後面試的時候如果被深究,坑害的還是自己!我在這裏像每一位星友保證,每一道面試題都是由自己精心整理,添加了一些面試的時候一些經驗,不僅說明了如何回答這個問題,還進一步介紹了被深究時的一些擴展問題,希望能夠實實在在的幫助大家!

另外,星球除了有一些高頻面試題的交流外,還有簡歷指導,模擬面試等很多服務哦!還有很多內部資料!截至目前,已經進行了50+次的建立指導和30+次的模擬面試,小夥伴們抓緊時間過來瞅一下吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章