天天看點

對hashcode和equal方法的了解

對hashcode和equal方法的了解

  • ​​如何了解hashCode的作用:​​
  • ​​Object.hashCode不可以代表記憶體位址​​
  • ​​改寫equals時總是要改寫hashCode​​

Java中的集合(Collection)是整個集合架構的基礎,它裡面存儲一組對象,表示不用的Collections,他的作用是維護一組對象的基本接口共兩類,一類是List,另一類是Set。前者集合内的元素是有序可重複的,後者無需不可重複。

要想保證元素不重複,可兩個元素是否重複應該依據什麼來判斷呢?這就是Object.equals方法了。但是,如果每增加一個元素就檢查一 次,那麼當元素很多時,後添加到集合中的元素比較的次數就非常多了。也就是說,如果集合中現在已經有1000個元素,那麼第1001個元素加入集合時,它 就要調用1000次equals方法。這顯然會大大降低效率。

于是,Java采用了哈希表的原理。雜湊演算法也稱為雜湊演算法,是将資料依特定算法直接指定到一個位址上。這樣一來,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的實體位置上。如果這個位置上沒有元素,它就可以 直接存儲在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,就調用它的equals方法與新元素進行比較,相同的話就不存了;不相同,也就是發生了Hash key相同導緻沖突的情況,那麼就有開放位址法、再hash法、鍊位址法等,在HashMap中采用的方法是鍊位址法來解決沖突。在這個Hash key的地方産生一個連結清單,将所有産生相同hashcode的對象放到這個單連結清單上去,串在一起。是以這裡存在一個沖突解決的問題(很少出現)。這樣一來實際調用equals方法的次數就大大降低了,幾乎隻需要一兩次。

是以,Java對于eqauls方法和hashCode方法是這樣規定的:

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

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

如何了解hashCode的作用:

談起hashcode,我們以java.lang.Object來了解,JVM每new一個Object,它都會将這個Object丢到一個Hash哈希表中去,這樣的話,下次做Object的比較或者取這個對象的時候,它會根據對象的hashcode再從Hash表中取這個對象。這樣做的目的是提高取對象的效率。

具體過程是這樣:

  1. new Object(),JVM根據這個對象的Hashcode值,放入到對應的Hash表對應的Key上,如果不同的對象确産生了相同的hash值,也就是發生了Hash key相同導緻沖突的情況,那麼就在這個Hash key的地方産生一個連結清單,将所有産生相同hashcode的對象放到這個單連結清單上去,串在一起。
  2. 比較兩個對象的時候,首先根據他們的hashcode去hash表中找他的對象,當兩個對象的hashcode相同,那麼就是說他們這兩個對象放在Hash表中的同一個key上,那麼他們一定在這個key上的連結清單上。那麼此時就隻能根據Object的equal方法來比較這個對象是否equal。當兩個對象的hashcode不同的話,肯定他們不能equal.

Object.hashCode不可以代表記憶體位址

改寫equals時總是要改寫hashCode

  1. 在一個應用程式執行期間,如果一個對象的equals方法做比較所用到的資訊沒有被修改的話,則對該對象調用hashCode方法多次,它必須始終如一地傳回同一個整數。
  2. 如果兩個對象根據equals(Object o)方法是相等的,則調用這兩個對象中任一對象的hashCode方法必須産生相同的整數結果。
  3. 如果兩個對象根據equals(Object o)方法是不相等的,則調用這兩個對象中任一個對象的hashCode方法,不要求産生不同的整數結果。但如果能不同,則可能提高散清單的性能。