淺析equals和hashCode

Object中equals方法的實(shí)現(xiàn)原理:

equals方法用于檢測(cè)一個(gè)對(duì)象是否與另外一個(gè)對(duì)象相等。而在Object類中這個(gè)方法實(shí)際上是判斷兩個(gè)對(duì)象是否具有相同他的引用,如果有信不,則相等吃嘿。

Public Boolean equals(object obj){
  return (this == obj)
}

所有對(duì)象都擁有標(biāo)識(shí)(內(nèi)存地址)和狀態(tài)(數(shù)據(jù)),同時(shí)“==”比較兩個(gè)對(duì)象的內(nèi)存地址币叹,所以說Object的equals()方法是比較兩個(gè)對(duì)象的內(nèi)存地址是否相等姨拥。
若object1.equals(object2)為true绅喉,標(biāo)識(shí)objects1和object2實(shí)際上是引用同一個(gè)對(duì)象

equals()與 == 的區(qū)別:

默認(rèn)情況下從超類object繼承而來的equals()方法與“==”是完全等價(jià)的,比較的都是對(duì)像的內(nèi)存地址叫乌,但是我們可以通過重寫equals方法柴罐,使其按照我們的需求的方式進(jìn)行比較,比如String類重寫了equals方法憨奸,比較的是字符的序列革屠,而不再是內(nèi)存地址。

equals方法的特性:

  • 自反性(x.equals(x)必須返回true)
  • 對(duì)稱性(x.equals(y)返回true時(shí)排宰,y.equals(x)也必須返回true)
  • 傳遞性(x.equals(y)和y.equals(z)都返回true時(shí)似芝,x.equals(z)也必須返回true)
  • 一致性(當(dāng)x和y引用的對(duì)象信息沒有被修改時(shí),多次調(diào)用x.equals(y)應(yīng)該得到同樣的返回值)
  • 對(duì)于任何非null值的引用x额各,x.equals(null)必須返回false国觉。

為什么重寫equal()的同時(shí)還要重寫hashCode():

hashCode是散列碼吧恃,哈希碼虾啦,是由對(duì)象到處的一個(gè)整型值,散列碼是沒有規(guī)律的,如果x與y是兩個(gè)不同的對(duì)象傲醉,那么它們的散列碼基本不會(huì)相同蝇闭。在Java中,我們可以使用hashCode()來獲取對(duì)象的散列碼硬毕,其值就是對(duì)象的存儲(chǔ)地址呻引,這個(gè)方法在Object類中聲明,因此所有的子類都含有這個(gè)方法吐咳。
《Effective Java》中對(duì)hashCode的約定:

1.在Java應(yīng)用程序執(zhí)行期間逻悠,如果equals方法比較中所用的信息沒有被修改,那么在同一個(gè)對(duì)象多次調(diào)用hashCode方法必須一致地返回相同地整數(shù)韭脊。如果多次執(zhí)行同一個(gè)應(yīng)用童谒,不要求該整數(shù)必須相同。

2.如果兩個(gè)對(duì)象通過調(diào)用equals方法是相等的沪羔,那么這兩個(gè)對(duì)象調(diào)用hashCode方法必須返回相同的整數(shù)

3.如果兩個(gè)對(duì)象通過調(diào)用equals方法是不相同的饥伊,不要求這兩個(gè)對(duì)像調(diào)用hashCode方法必須返回不同的整數(shù)。但是程序員應(yīng)該意識(shí)到對(duì)不同的對(duì)象產(chǎn)生不同的hash值可以提供哈希表的性能蔫饰。

《Java編程思想》中對(duì)第一條進(jìn)行說明:

“設(shè)計(jì)hashCode()時(shí)最重要的因素就是:無論何時(shí)琅豆,對(duì)同一個(gè)對(duì)象調(diào)用hashCode()都應(yīng)該產(chǎn)生同樣的值。如果在講一個(gè)對(duì)象用put()添加進(jìn)HashMap時(shí)產(chǎn)生一個(gè)HashCode值篓吁,而用get()取出時(shí)卻產(chǎn)生了另一個(gè)hashCode值茫因,那么就無法獲取該對(duì)象了。所以如果你的hashCode方法依賴于對(duì)象中易變的數(shù)據(jù)杖剪,用戶就要當(dāng)心了节腐,因?yàn)榇藬?shù)據(jù)發(fā)生變化時(shí),hashCode()方法就會(huì)生成一個(gè)不同的散列碼摘盆∫砣福”

由上可知,在Object類中孩擂,hashCode方法是通過Object對(duì)象的地址計(jì)算出來的狼渊,因?yàn)镺bject對(duì)象只與自身相等,多以同一個(gè)對(duì)象的地址總是相等的类垦,計(jì)算取得的哈希碼也必然相等狈邑,對(duì)于不同的對(duì)象,由于地址不同蚤认,所獲取的哈希碼自然也不會(huì)相等米苹。所以如果一個(gè)類重寫了equals方法,但沒有重寫hashCode方法砰琢,違反了第2條規(guī)定蘸嘶。

重寫equals()中g(shù)etClass與instanceof的區(qū)別:

重寫equals()方法時(shí)良瞧,一般推薦使用getClass來進(jìn)行類型判斷,除非所有的子類有統(tǒng)一的語義才使用instanceof训唱。Instanceof的作用時(shí)判斷左邊對(duì)象是否為右邊類的實(shí)例褥蚯,返回boolean類型的數(shù)據(jù)】鲈觯可以用來判斷繼承中的子類的實(shí)例是否為父類的實(shí)現(xiàn)赞庶。

實(shí)現(xiàn)高質(zhì)量的equals方法的訣竅:

  • 使用==操作符檢查:參數(shù)是否為這個(gè)對(duì)象的引用
  • 使用instanceof操作符檢查:參數(shù)是否為正確的類型
  • 對(duì)于類中的關(guān)鍵屬性,檢查參數(shù)傳入對(duì)象的屬性是否與之相配
  • 編寫完equals方法后澳骤,問自己它是否滿足對(duì)稱性歧强,傳遞性,一致性
  • 重寫equals時(shí)總是要重寫hashCode
  • 不要將equals方法參數(shù)中的object對(duì)象替換為其他的類型为肮,在重寫時(shí)不要忘記@override注解
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Person))
        return false;
    Person p = (Person) o;
    return name.equals(p.name) && age == p.age;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末誊锭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弥锄,更是在濱河造成了極大的恐慌丧靡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡毡证,警方通過查閱死者的電腦和手機(jī)净蚤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事÷笨遥” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寒矿,是天一觀的道長(zhǎng)突琳。 經(jīng)常有香客問我,道長(zhǎng)符相,這世上最難降的妖魔是什么拆融? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮啊终,結(jié)果婚禮上镜豹,老公的妹妹穿的比我還像新娘。我一直安慰自己蓝牲,他們只是感情好趟脂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著例衍,像睡著了一般昔期。 火紅的嫁衣襯著肌膚如雪已卸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天镇眷,我揣著相機(jī)與錄音咬最,去河邊找鬼翎嫡。 笑死欠动,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惑申。 我是一名探鬼主播具伍,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼圈驼!你這毒婦竟也來了人芽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤绩脆,失蹤者是張志新(化名)和其女友劉穎萤厅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體靴迫,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惕味,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玉锌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片名挥。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖主守,靈堂內(nèi)的尸體忽然破棺而出禀倔,到底是詐尸還是另有隱情,我是刑警寧澤参淫,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布救湖,位于F島的核電站,受9級(jí)特大地震影響涎才,放射性物質(zhì)發(fā)生泄漏捎谨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一憔维、第九天 我趴在偏房一處隱蔽的房頂上張望涛救。 院中可真熱鬧,春花似錦业扒、人聲如沸检吆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹭沛。三九已至臂寝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摊灭,已是汗流浹背咆贬。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帚呼,地道東北人掏缎。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像煤杀,于是被迫代替她去往敵國和親眷蜈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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