簡(jiǎn)單解讀equals()與“==”、hashcode()的關(guān)系

一屎篱、"=="和equals方法究竟有什么區(qū)別?

  • ==操作符專門用來比較兩個(gè)變量的值是否相等葵蒂,也就是用于比較變量所對(duì)應(yīng)的內(nèi)存中所存儲(chǔ)的數(shù)值是否相同交播,要比較兩個(gè)基本類型的數(shù)據(jù)或兩個(gè)引用變量是否相等,只能用==操作符践付。
    如果一個(gè)變量指向的數(shù)據(jù)是對(duì)象類型的秦士,那么,這時(shí)候涉及了兩塊內(nèi)存永高,對(duì)象本身占用一塊內(nèi) 存(堆內(nèi)存)隧土,變量也占用一塊內(nèi)存,例如Objet obj = new Object();變量obj是一個(gè)內(nèi)存命爬,new Object()是另一個(gè)內(nèi)存(堆內(nèi)存),此時(shí),變量obj所對(duì)應(yīng)的內(nèi)存中存儲(chǔ)的數(shù)值就是對(duì)象占用的那塊內(nèi)存(堆內(nèi)存)的首地址奥裸。對(duì)于指向?qū)ο箢愋偷淖兞扛抛鳎绻容^兩個(gè)變量是否指向同一個(gè)對(duì)象,即要看這兩個(gè)變量所對(duì)應(yīng)的內(nèi)存中的數(shù)值是否相等艇抠,這時(shí)候就需要用==操作符進(jìn)行比較幕庐。
  • equals方法是用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同,就好比去比較兩個(gè)人的長(zhǎng)相是否相同家淤,它比較的兩個(gè)對(duì)象是獨(dú)立的异剥。例如,對(duì)于下面的代碼:
    String a=new String("foo");
    String b=new String("foo");
    兩條new語句創(chuàng)建了兩個(gè)對(duì)象絮重,然后用a/b這兩個(gè)變量分別指向了其中一個(gè)對(duì)象冤寿,這是兩個(gè)不同的對(duì)象错妖,它們的首地址是不同的,即a和b中存儲(chǔ)的數(shù)值(對(duì)應(yīng)對(duì)象的首地址)是不相同的疚沐,所以暂氯,表達(dá)式a==b將返回false,而這兩個(gè)對(duì)象中的內(nèi)容是相同的亮蛔,所以痴施,表達(dá)式a.equals(b)將返回true。

如果一個(gè)類沒有自己定義equals方法(就比如之前創(chuàng)建的User類)究流,那么它將繼承Object類的equals方法辣吃,Object類的equals方法的實(shí)現(xiàn)源代碼如下:

      public boolean equals(Object o) {
           return this == o;
       }

這說明,如果一個(gè)類沒有自己定義equals方法芬探,它默認(rèn)的equals方法(從Object類繼承的)就是使用==操作符神得,也是在比較兩個(gè)變量指向的對(duì)象是否是同一對(duì)象,這時(shí)候使用equals和使用==會(huì)得到同樣的結(jié)果偷仿,如果比較的是兩個(gè)獨(dú)立的對(duì)象則總返回false哩簿。

二、equals()與hashcode()

hashCode()方法和equals()方法的作用其實(shí)一樣酝静,在Java里都是用來對(duì)比兩個(gè)對(duì)象是否相等一致节榜,那么equals()既然已經(jīng)能實(shí)現(xiàn)對(duì)比的功能了,為什么還要hashCode()呢别智?

因?yàn)橹貙懙膃quals()里一般比較的比較全面比較復(fù)雜宗苍,這樣效率就比較低,而利用hashCode()進(jìn)行對(duì)比薄榛,則只要生成一個(gè)hash值進(jìn)行比較就可以了讳窟,效率很高,那么hashCode()既然效率這么高為什么還要equals()呢敞恋?

因?yàn)閔ashCode()并不是完全可靠丽啡,有時(shí)候不同的對(duì)象他們生成的hashcode也會(huì)一樣(hash沖突),所以hashCode()只能說是大部分時(shí)候可靠耳舅,并不是絕對(duì)可靠碌上,所以可以得出:

  • equals()相等的兩個(gè)對(duì)象他們的hashCode()肯定相等,也就是用equals()對(duì)比是絕對(duì)可靠的浦徊。
  • hashCode()相等的兩個(gè)對(duì)象他們的equals()不一定相等馏予,也就是hashCode()不是絕對(duì)可靠的

那是不是重寫了equals()方法就一定要重寫hashCode()方法呢盔性?
一般來說涉及到對(duì)象之間的比較大小就需要重寫equals方法霞丧,但是不是重寫了equals就需要重寫hashCode呢?實(shí)際上這只是一條規(guī)范冕香,如果不這樣做程序也可以執(zhí)行蛹尝,只不過會(huì)存在潛在bug后豫。一般一個(gè)類的對(duì)象如果會(huì)存儲(chǔ)在HashTable,HashSet,HashMap等散列存儲(chǔ)結(jié)構(gòu)中,那么重寫equals后最好也重寫hashCode突那,否則會(huì)導(dǎo)致存儲(chǔ)數(shù)據(jù)的不唯一性(存儲(chǔ)了兩個(gè)equals相等的數(shù)據(jù))挫酿。而如果確定不會(huì)存儲(chǔ)在這些散列結(jié)構(gòu)中,則可以不重寫hashCode愕难。但是個(gè)人覺得還是重寫hashCode比較好一點(diǎn)早龟,這樣就不用考慮后期存儲(chǔ)在哪些結(jié)構(gòu)中,況且重寫了hashCode也不會(huì)降低性能猫缭,因?yàn)樵诰€性結(jié)構(gòu)(如ArrayList)中是不會(huì)調(diào)用hashCode葱弟。

下面看一下一個(gè)對(duì)象放入散列集合的大致流程:

  1. 準(zhǔn)備即將放入集合的對(duì)象
  2. 判斷集合中是否存在hashCode值與這個(gè)對(duì)象相等的對(duì)象
    • 存在hashCode值相等的對(duì)象
      判斷該對(duì)象和要放入對(duì)象的equals是否相等
      • 相等 --> 直接丟棄
      • 不相等 --> 存入集合
    • 不存在hashCode值相等的集合
      直接存入集合

所有對(duì)于需要大量并且快速的對(duì)比的話如果都用equals()去做顯然效率太低,所以解決方式是猜丹,每當(dāng)需要對(duì)比的時(shí)候芝加,首先用hashCode()去對(duì)比,如果hashCode()不一樣射窒,則表示這兩個(gè)對(duì)象肯定不相等(也就是不必再用equals()去再對(duì)比了),如果hashCode()相同藏杖,此時(shí)再對(duì)比他們的equals(),如果equals()也相同轮洋,則表示這兩個(gè)對(duì)象是真的相同了制市,這樣既能大大提高了效率也保證了對(duì)比的絕對(duì)正確性!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弊予,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子开财,更是在濱河造成了極大的恐慌汉柒,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件责鳍,死亡現(xiàn)場(chǎng)離奇詭異碾褂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)历葛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門正塌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恤溶,你說我怎么就攤上這事乓诽。” “怎么了咒程?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵鸠天,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我帐姻,道長(zhǎng)稠集,這世上最難降的妖魔是什么奶段? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮剥纷,結(jié)果婚禮上痹籍,老公的妹妹穿的比我還像新娘。我一直安慰自己晦鞋,他們只是感情好蹲缠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鳖宾,像睡著了一般吼砂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鼎文,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天渔肩,我揣著相機(jī)與錄音,去河邊找鬼拇惋。 笑死周偎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撑帖。 我是一名探鬼主播蓉坎,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼胡嘿!你這毒婦竟也來了蛉艾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤衷敌,失蹤者是張志新(化名)和其女友劉穎勿侯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缴罗,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡助琐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了面氓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兵钮。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖舌界,靈堂內(nèi)的尸體忽然破棺而出掘譬,到底是詐尸還是另有隱情,我是刑警寧澤禀横,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布屁药,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酿箭。R本人自食惡果不足惜复亏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缭嫡。 院中可真熱鬧缔御,春花似錦、人聲如沸妇蛀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽评架。三九已至眷茁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纵诞,已是汗流浹背上祈。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浙芙,地道東北人登刺。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嗡呼,于是被迫代替她去往敵國(guó)和親纸俭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 注:都是在百度搜索整理的答案南窗,如有侵權(quán)和錯(cuò)誤揍很,希告知更改。 一万伤、哪些情況下的對(duì)象會(huì)被垃圾回收機(jī)制處理掉 ?當(dāng)對(duì)象對(duì)...
    Jenchar閱讀 3,226評(píng)論 3 2
  • 本文出自 Eddy Wiki 女轿,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,161評(píng)論 0 16
  • 【Day11】今日閱讀《拆掉思維里的墻》 P120-P168 《肖申克的救贖》里有一句精典臺(tái)詞:肖申克監(jiān)獄里沒有...
    橘子669閱讀 120評(píng)論 1 0
  • 沉默的老好人——沙僧 文/張守權(quán) 提及《西游記》中的沙僧,給人們最為直接的印象往往是一個(gè)忠實(shí)可靠壕翩、正直憨厚...
    張守權(quán)閱讀 1,465評(píng)論 0 3
  • ——亂世迷離,你我安在傅寡? 歲月是一場(chǎng)兵荒馬亂的戰(zhàn)爭(zhēng)放妈, 有人丟失了勇氣, 有人丟失了自己荐操, 經(jīng)過這場(chǎng)戰(zhàn)爭(zhēng)后芜抒, 有些人...
    老大閱讀 170評(píng)論 0 2