天天看點

深入了解hashCode()和equals()方法的關系。

1.首先要明白hashCode()和equals()方法的作用。

hashCode():根據對象的記憶體位址計算出哈希值
           
/**
傳回一個對象的散列碼,這個方法有利于哈希表,例如HashMap
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. 
*/
    public native int hashCode();
           
equals():根據記憶體位址,對比兩個對象是否相等,有一個java基礎問題,equals和 == 的差別?
           

2.為什麼要有hashCode()和equals()方法呢?

Java中的Collection有兩類,一類是List,一類是Set。

深入了解hashCode()和equals()方法的關系。
  • List内的元素是有序的,元素可以重複。Set元素無序,但元素不可重複。要想保證元素不重複,應該依據什麼來判斷呢?你可能會想:這容易呀,直接調用元素對象的 equals() 方法進行比較不就行了嗎?如果容器中的存儲的對象數量較少,這确實是個好主意,但是如果容器中存放的對象達到了一定的規模,要調用容器中所有對象的 equals() 方法和新元素進行比較,就不是一件容易的事情了。 equals() 方法的比較邏輯簡單無比,總的來說也是一個時間複雜度為 O(n) 的操作,效率成為大問題。
  • 這時候hashCode的作用就展現了,散清單的查詢效率是O(1),每個對象都自帶有 hashCode(),這個 hashCode 将會用作散清單哈希函數的輸入,hashCode 經過哈希函數計算後得到哈希值,新對象會根據哈希值,存儲到相應的記憶體的單元。這樣一來,每一個要對比的對象隻需要對比哈希值就能夠完成,加入新元素時,這個新加入的元素已經存在,需要另作處理:覆寫掉原來的元素(key)或舍棄。

3.資料量更大了,又出問題了!!!

  • 當輸入樣本量足夠大時,不相同的輸入是會産生相同輸出的,也就是形成哈希沖突(看hashcode的原理吧)。這時候該怎麼辦呢?
  • ==hashCode()和equals()方法結合使用!==當出現兩個對象hashCode相等時,再調用equals方法對比,如果相等,則認為他們是同一個對象。這樣既提高了效率,又能保證準确性。
  • 那麼有面試題“兩個對象的 hashCdoe() 相同,它的 equals() 方法一定要傳回 true,對嗎?”,錯誤!!理由如上