Java中重寫equals方法為什麼要重寫hashcode方法?

2020-12-22 計算機java編程

== 與 equals的區別

如果兩個引用類型變量使用==運算符,那麼比較的是地址,它們分別指向的是否是同一地址的對象。結果一定是false,因為兩個對象不可能存放在同一地址處。要求是兩個對象都不是能空值,與空值比較返回false。==不能實現比較對象的值是否相同。所有對象都有equals方法,默認是Object類的equals,其結果與==一樣。如果希望比較對象的值相同,必須重寫equals方法。hashCode與equals的區別

Object中的equals:

equals 方法要求滿足:

自反性 a.equals(a)對稱性 x.equals(y) y.equals(x)一致性 x.equals(y) 多次調用結果一致對於任意非空引用x,x.equals(null) 應該返回falseObject中的hashCode:

它是一個本地方法,它的實現與本地機器有關,這裡我們暫且認為他返回的是對象存儲的物理位置。

當equals方法被重寫時,通常有必要重寫hashCode方法,以維護hashCode方法的常規約定:值相同的對象必須有相同的hashCode。object1.equals(object2)為true,hashCode也相同;hashCode不同時,object1.equals(object2)為false;hashCode相同時,object1.equals(object2)不一定為true;當我們向一個Hash結構的集合中添加某個元素,集合會首先調用hashCode方法,這樣就可以直接定位它所存儲的位置,若該處沒有其他元素,則直接保存。若該處已經有元素存在,就調用equals方法來匹配這兩個元素是否相同,相同則不存,不同則鏈到後面(如果是鏈地址法)。

先調用hashCode,唯一則存儲,不唯一則再調用equals,結果相同則不再存儲,結果不同則散列到其他位置。因為hashCode效率更高(僅為一個int值),比較起來更快。

HashMap#put源碼

hash是key的hash值,當該hash對應的位置已有元素時會執行以下代碼(hashCode相同)

如果equals返回結果相同,則值一定相同,不再存入。

如果重寫equals不重寫hashCode會怎樣

兩個值不同的對象的hashCode一定不一樣,那麼執行equals,結果為true,HashSet或HashMap的鍵會放入值相同的對象。

話不多說,直接上例子,~~~

首先我們只重寫equals()方法

看我們的測試類

依次輸出

是否出現矛盾???用equals比較說明對象相同,但是在HashMap中卻以不同的對象存儲(沒有重寫hascode值,兩個hascode值,在他看來就是兩個對象)。到底這兩個對象相等不相等????說明必須重寫hashCode()的重要性,

接下來重寫重寫equals方法和hashCode方法,再比較

測試類

依次輸出

看到這裡,同學 你懂了嗎?還不懂,可以自己實現一遍代碼。

相關焦點

  • Java為什麼重寫equals一定要重寫hashCode?
    初步探索首先我們要了解equals方法是什麼,hashcode方法是什麼。equals方法equals 是java的obejct類的一個方法,equals的源碼如下:由此我們可以看到equals是用來比較兩個對象的內存地址是否相等。
  • Java面試題之為什麼要重寫hashcode( )和equals( )?
    hello,大家好,又到了今天的java知識分享時刻,每一次的努力都是在為美好的明天做積累,每天花一點點時間,讓知識更牢固一些!好了,請看下題:為什麼要重寫hashcode( )和equals( )?那麼就換另外一種登記方式,前臺登記時登記身份證號,警察來前臺找身份證號時發現身份證號也存在重複,經過哈希算法進行計算後相同的hashcode值被分到了一個房間然後產生鍊表,鍊表查詢效率非常慢,然後警察找的時候也會遇到問題。那麼只能換第三種登記方式了,前臺登記時同時登記身份證號和名字,這樣警察來找的時候同時按照兩個條件去查,這樣就能直接鎖定要找的人在哪個房間。
  • 重寫equals()時為什麼要重寫hashcode
    重寫equals()方法時,為什麼要重寫hashcode方法?1.==和equals()的區別(1)== 是比較運算符,equals()是在Object中定義的一個方法。3.重寫equals()方法時,為什麼要重寫hashcode方法?
  • 經典面試題:重寫equals方法時,為什麼必須重寫hashCode方法?
    大家好,這裡是java研究所。今天給大家來個經典面試題:重寫equals方法時,為什麼必須重新hashCode方法?這2個方法位於Object類中,Object類是所有類的父類,所以如果你的類中沒有重寫這2個方法時,默認將使用Object中的這2個方法。
  • 為什麼要重寫 hashcode 和 equals 方法?
    hashcode方法?為什麼要重寫equals和hashCode方法當我們用HashMap存入自定義的類時,如果不重寫這個自定義類的equals和hashCode方法,得到的結果會和我們預期的不一樣。我們來看WithoutHashCode.java這個例子。在其中的第2到第18行,我們定義了一個Key類;在其中的第3行定義了唯一的一個屬性id。
  • 淺談Java中的hashcode方法
    為什麼這麼說呢?考慮一種情況,當向集合中插入對象時,如何判別在集合中是否已經存在該對象了?(注意:集合中不允許重複的元素存在)也許大多數人都會想到調用equals方法來逐個進行比較,這個方法確實可行。但是如果集合中已經存在一萬條數據或者更多的數據,如果採用equals方法去逐一比較,效率必然是一個問題。
  • 淺談 Java 中的 hashcode 方法
    此時hashCode方法的作用就體現出來了,當集合要添加新的對象時,先調用這個對象的hashCode方法,得到對應的hashcode值,實際上在HashMap的具體實現中會用一個table保存已經存進去的對象的hashcode值,如果table中沒有該hashcode值,它就可以直接存進去,不用再進行任何比較了;如果存在該hashcode值, 就調用它的equals方法與新元素進行比較,相同的話就不存了
  • 「原創」不重寫equals和hashcode難道就不行嗎?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫究竟為什麼要重寫equals和hashcode???>2、Hash算法介紹3、重寫equals()方法和hashCode()方法3.1、什麼時候需要重寫?
  • 詳解equals()方法和hashCode()方法
    與equals()方法類似,hashCode()方法可以被重寫。JDK中對hashCode()方法的作用,以及實現時的注意事項做了說明:(1)hashCode()在哈希表中起作用,如java.util.HashMap。(2)如果對象在equals()中使用的信息都沒有改變,那麼hashCode()值始終不變。
  • 乾貨 | 名企高頻考點-Java hashCode() 方法 和 equals() 方法
    在Java中存在兩個比較方法,分別是:hashCode() 方法 和 equals() 方法。為什麼我們有時候要重寫hashCode() 方法 和 equals() 方法?1. 你知道hashCode() 方法 和 equals() 方法嗎?當被面試官問到這個問題的時候,我們首先需要回答清楚兩個方法在沒有重寫之前,他們是如何工作的?
  • 面試官問我:hashcode 是什麼?和equals是兄弟嗎?
    秋招的時候還記得面試官問過我hashcode是什麼,對於int、long、string類型的hashcode有什麼區別,和equals一起是怎麼使用的,為什麼重寫hashcode的同時也要重寫equals。      八股文背多了,也只是會表面,有空的時候還是整理一下,順便寫了幾個例子加深下印象。hashcode 是什麼?
  • 簡單的理解集合中的HashSet和HashTree幾個重寫方法
    面試中相信小夥伴都會遇到這個問題,我們快來了解下HashSet和HashTree重寫機制吧!!!Java中的set是無序的,但是是不可重複的HashSet底層是哈希表,通過調用hashcode和equals方法實現去重當我們HashSet裡面存的是字符串時,就能默認去重了,因為String已經重寫了hashcode和euqals方法public static void main(String[] args) {HashSet
  • 『Java系列文章』2、淺談equals()和hashcode()
    對於Object類來說,equals()方法在對象上實現的是差別可能性最大的等價關係,即,對於任意非null的引用值x和y,若且唯若x和y引用的是同一個對象,該方法才會返回true。需要注意的是當equals()方法被override時,hashCode()也要被override。按照一般hashCode()方法的實現來說,相等的對象,它們的hash code一定相等。
  • Object類中的equals和hashCode方法,你真的了解嗎?
    前言在Java中,equals和hashCode方法是Object中提供的兩個方法,這兩個方法對以後的學習有很大的幫助,本文就深度來去講解這兩個方法。多說一句,我們直接從JDK的文檔來去解釋。 這個方法返回true若且唯若x和y指向了同樣的對象(x==y),這句話也就是說明了在默認情況下,Object類中的equals方法默認比較的是對象的地址,因為只有是相同的地址才會相等(x == y),如果沒有重寫equals方法,那麼默認就是比較的是地址。
  • equals 和 hashCode 到底有什麼聯繫?一文告訴你!
    可以看出,hashCode()是一個native方法,而且返回值類型是整形;實際上,該native方法將對象在內存中的地址作為哈希碼返回,可以保證不同對象的返回值不同。與equals()方法類似,hashCode()方法可以被重寫。
  • 不懂得hashcode的重要性,程序的性能會大打折扣
    hashcode這個問題要分情況回答:第一種:如果沒有重寫equals和hashcode,那默認就是使用Object的,Object中比較的是對象地址,如果2個對象相同,hashcode是肯定相同的。既然提到自己重寫equals和hashcode,那我就需要遵守java的規則:equals必須滿足自反性、對稱性、傳遞性、一致性,對於任意不為null的引用值x,x.equals(null)返回false;如果兩個對象相同(equals方法返回true),那麼它們的hashCode值一定要相同,如果兩個對象的hashCode相同,它們並不一定相同。
  • Java hashCode() 方法深入理解
    Java.lang.Object 有一個hashCode()和一個equals()方法,這兩個方法在軟體設計中扮演著舉足輕重的角色。
  • hashCode和identityHashCode的區別你知道嗎?
    identityHashCodeidentityHashCode是System裡面提供的本地方法,java.lang.System#identityHashCode。 * The hash code for the null reference is zero.
  • equals方法
    今天主要來講java中的equals方法1.equals是一個方法而非運算符,所以只使用於引用數據類型。
  • 【答疑解惑】Java中的默認構造器和equals方法
    int m; //默認構造方法 A() { } //重載的構造方法 A(int i) { m = i; } }A a = new A()會調用默認構造函數,A a1 = new A(1)會調用第二個你重載的構造函數。