這篇文章主要介紹“為什么要重寫equals和hashcode”,在日常操作中,相信很多人在為什么要重寫equals和hashcode問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”為什么要重寫equals和hashcode”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
首先我們分別解釋equals()方法和hashCode()方法分別是用來做什么的?
我們再來看equals()方法和hashCode()方法兩者有什么關系?
最后來看為什么重寫equals()就一定要重寫hashCode()方法?
equals()方法:
很明顯,該方法就是用來判斷兩個對象是否是同一個對象。在Object類源碼(如下所示)中,其底層是使用了“==”來實現,也就是說通過比較兩個對象的內存地址是否相同判斷是否是同一個對象。
public boolean equals(Object obj){
return (this == obj); }但是在實際應用中,該方法不能滿足的我們的需求。因為我們認為兩個對象即使不是指向的同一塊內存,只要這兩個對象的各個字段屬性值都相同,那么就認為這兩個對象是同一個對象。所以就需要重寫equals()方法,即如果兩個對象指向內存地址相同或者兩個對象各個字段值相同,那么就是同一個對象。
hashCode()方法:
一提到hashcode,很自然就想到哈希表。將某一key值映射到表中的一個位置,從而達到以O(1)的時間復雜度來查詢該key值。Object類源碼(如下所示)中,hashCode()是一個native方法,哈希值的計算利用的是內存地址。
public native int hashCode();
可以認為利用哈希表也能起到一定的判重的作用,但是現實是可能存在哈希沖突,即使是兩個不同的對象,他們的哈希值也可能相同,如何解決哈希沖突,這里就略略略了??傊?,我們記住哈希表具有優越的查詢性能,并且存在哈希沖突。
兩者事實關系如下:
如果兩個對象相同(即用equals比較返回true),那么它們的hashCode值一定要相同?。。。?;
如果兩個對象不同(即用equals比較返回true),那么它們的hashCode值可能相同也可能不同;
如果兩個對象的hashCode相同(存在哈希沖突),那么它們可能相同也可能不同(即equals比較可能是false也可能是true)
如果兩個對象的hashCode不同,那么他們肯定不同(即用equals比較返回false)
對于對象集合的判重,如果一個集合含有10000個對象實例,僅僅使用equals()方法的話,那么對于一個對象判重就需要比較10000次,隨著集合規模的增大,時間開銷是很大的。但是同時使用哈希表的話,就能快速定位到對象的大概存儲位置,并且在定位到大概存儲位置后,后續比較過程中,如果兩個對象的hashCode不相同,也不再需要調用equals()方法,從而大大減少了equals()比較次數。 所以從程序實現原理上來講的話,既需要equals()方法,也需要hashCode()方法。那么既然重寫了equals(),那么也要重寫hashCode()方法,以保證兩者之間的配合關系。
? 開放定址法: 這種方法也稱再散列法,其基本思想是:當關鍵字key的哈希地址p=H(key)出現沖突時,以p為基礎,產生另一個哈希地址p1,如果p1仍然沖突,再以p為基礎,產生另一個哈希地址p2,…,直到找出一個不沖突的哈希地址pi ,將相應元素存入其中。這種方法有一個通用的再散列函數形式: ? 線性探測再散列: 這種方法的特點是:沖突發生時,順序查看表中下一單元,直到找出一個空單元或查遍全表。 ? 二次探測再散列 這種方法的特點是:沖突發生時,在表的左右進行跳躍式探測,比較靈活。
到此,關于“為什么要重寫equals和hashcode”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。