Equals抓歼、hashCode()、==的區(qū)別

==

進(jìn)行等值比較
java中的數(shù)據(jù)類型分為:

  1. 基本數(shù)據(jù)類型(原始數(shù)據(jù)類型)
    (byte,short,char,int,long,float,double,boolean)
    這些數(shù)據(jù)的值直接存儲(chǔ)在Java棧中拢锹,他們之間的比較應(yīng)使用雙等號(hào)(==)谣妻。
  2. 引用類型(類、接口卒稳、數(shù)組)
    使用(==)對此類數(shù)據(jù)進(jìn)行比較時(shí)比較的是實(shí)際的數(shù)據(jù)在內(nèi)存中的存放地址蹋半。因此,只有當(dāng)兩個(gè)變量引用的是同一個(gè)對象時(shí)充坑,使用(==)比較時(shí)結(jié)果才為true减江,否則結(jié)果為false染突。
對象本身是放在堆中的,棧中存放的是對象的引用(地址)辈灼。
由此可見'=='是對棧中的值進(jìn)行比較的份企。
如果要比較堆中對象的內(nèi)容是否相同,那么就要重寫equals方法茵休。

equals()

①默認(rèn)情況下薪棒,若沒有重寫equals方法手蝎,調(diào)用equals方法時(shí)都是調(diào)用Object類的equals方法榕莺,而Object的equals方法主要用于判斷對象的內(nèi)存地址引用是不是同一個(gè)地址(是不是同一個(gè)對象)。下面是Object類中equals方法:

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

此時(shí)棵介,equals()和==時(shí)等效的钉鸯。

②若類中覆蓋了equals方法,那么需要根據(jù)具體的代碼來確定equals方法的作用
例如邮辽,String類重寫了equals()方法:

public boolean equals(Object anObject) {  
    if (this == anObject) {  
        return true;  
    }  
    if (anObject instanceof String) {  
        String anotherString = (String)anObject;  
        int n = count;  
        if (n == anotherString.count) {  
            char v1[] = value;  
            char v2[] = anotherString.value;  
            int i = offset;  
            int j = anotherString.offset;  
            while (n-- != 0) {  
                if (v1[i++] != v2[j++])  
                return false;  
            }  
            return true;  
        }  
    }  
    return false;  
}  

String中equals方法判斷相等的步驟是:

  1. 若A==B 即是同一個(gè)String對象 返回true

  2. 若對比對象是String類型則繼續(xù)唠雕,否則返回false

  3. 判斷A、B長度是否一樣吨述,不一樣的話返回false

  4. 逐個(gè)字符比較岩睁,若有不相等字符,返回false

重寫equals的注意點(diǎn):

  1. 自反性:對任意引用值X揣云,x.equals(x)的返回值一定為true.
  2. 對稱性:對于任何引用值x,y,當(dāng)且僅當(dāng)y.equals(x)返回值為true時(shí)捕儒,x.equals(y)的返回值一定為true;
  3. 傳遞性:如果x.equals(y)=true, y.equals(z)=true,則x.equals(z)=true
  4. 一致性:如果參與比較的對象沒任何改變,則對象比較的結(jié)果也不應(yīng)該有任何改變
  5. 非空性:任何非空的引用值X邓夕,x.equals(null)的返回值一定為false

重寫euqals的一般步驟:

  1. 使用==符號(hào)檢查“參數(shù)是否為這個(gè)對象的引用”刘莹。如果是,則返回true焚刚。這只不過是一種性能優(yōu)化点弯,如果比較操作有可能很昂貴,就值得這么做矿咕。
  2. 使用instanceof操作符檢查“參數(shù)是否為正確的類型”抢肛。如果不是,則返回false碳柱。一般來說雌团,所謂“正確的類型”是指equals方法所在的那個(gè)類。
  3. 把參數(shù)轉(zhuǎn)換成正確的類型士聪。因?yàn)檗D(zhuǎn)換之前進(jìn)行過instanceof測試锦援,所以確保會(huì)成功。
  4. 對于該類中的每個(gè)“關(guān)鍵”域剥悟,檢查參數(shù)中的域是否與該對象中對應(yīng)的域相匹配灵寺。如果這些測試全部成功曼库,則返回true;否則返回false。
  5. 當(dāng)編寫完成了equals方法之后略板,檢查“對稱性”毁枯、“傳遞性”、“一致性”叮称。

hashCode()

hashCode() 的作用是獲取哈希碼种玛,也稱為散列碼;它實(shí)際上是返回一個(gè)int整數(shù)瓤檐。hash碼的主要用途就是確定該對象在哈希表中的索引位置赂韵,據(jù)此很容易推斷出,我們需要每個(gè)對象的hash碼盡可能不同挠蛉,這樣才能保證散列的存取性能祭示。

事實(shí)上,Object類提供的默認(rèn)實(shí)現(xiàn)確實(shí)保證每個(gè)對象的hash碼不同(在對象的內(nèi)存地址基礎(chǔ)上經(jīng)過特定算法返回一個(gè)hash碼)谴古。Java采用了哈希表的原理质涛。哈希(Hash)實(shí)際上是個(gè)人名,由于他提出一哈希算法的概念掰担,所以就以他的名字命名了汇陆。

hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)带饱。

簡單來說毡代,hashCode()方法是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。 散列函數(shù)將任意長度的二進(jìn)制值映射為較短的固定長度的二進(jìn)制值纠炮,這個(gè)小的二進(jìn)制值稱為哈希值月趟。

hashCode()和equals()的聯(lián)系

  1. 同一對象上多次調(diào)用hashCode()方法,總是返回相同的整型值恢口。
  2. 如果兩個(gè)對象equals孝宗,Java運(yùn)行時(shí)環(huán)境會(huì)認(rèn)為他們的hashcode一定相等。
  3. 如果兩個(gè)對象不equals耕肩,他們的hashcode有可能相等因妇。
  4. 如果兩個(gè)對象hashcode相等,他們不一定equals猿诸。
  5. 如果兩個(gè)對象hashcode不相等婚被,他們一定不equals。

重寫兩個(gè)方法時(shí)應(yīng)尊重的規(guī)范:

  • 若重寫equals(Object obj)方法梳虽,有必要重寫hashcode()方法址芯,確保通過equals(Object obj)方法判斷結(jié)果為true的兩個(gè)對象具備相等的hashcode()返回值。
  • 如果equals(Object obj)返回false,即兩個(gè)對象“不相同”谷炸,并不要求兩個(gè)對象的hashcode()方法返回兩個(gè)相同的值北专。

總結(jié)

  • equals方法用于比較對象的內(nèi)容是否相等(覆蓋以后)
  • hashcode方法只有在集合中用到
  • 當(dāng)覆蓋了equals方法時(shí),比較對象是否相等將通過覆蓋后的equals方法進(jìn)行比較(判斷對象的內(nèi)容是否相等)旬陡。
  • 將對象放入到集合中時(shí)拓颓,首先判斷要放入對象的hashcode值與集合中的任意一個(gè)元素的hashcode值是否相等,如果不相等直接將該對象放入集合中描孟。
    (如果hashcode值相等驶睦,然后再通過equals方法判斷要放入對象與集合中的任意一個(gè)對象是否相等,如果equals判斷不相等匿醒,直接將該元素放入到集合中场航,否則不放入。)

歡迎到作者github主頁交流

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末青抛,一起剝皮案震驚了整個(gè)濱河市旗闽,隨后出現(xiàn)的幾起案子酬核,更是在濱河造成了極大的恐慌蜜另,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫡意,死亡現(xiàn)場離奇詭異举瑰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蔬螟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門此迅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旧巾,你說我怎么就攤上這事耸序。” “怎么了鲁猩?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵坎怪,是天一觀的道長。 經(jīng)常有香客問我廓握,道長搅窿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任隙券,我火速辦了婚禮男应,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娱仔。我一直安慰自己沐飘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耐朴,像睡著了一般众弓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隔箍,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天谓娃,我揣著相機(jī)與錄音,去河邊找鬼蜒滩。 笑死滨达,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俯艰。 我是一名探鬼主播捡遍,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼竹握!你這毒婦竟也來了画株?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤啦辐,失蹤者是張志新(化名)和其女友劉穎谓传,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芹关,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡续挟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侥衬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诗祸。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖轴总,靈堂內(nèi)的尸體忽然破棺而出直颅,到底是詐尸還是另有隱情,我是刑警寧澤怀樟,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布功偿,位于F島的核電站,受9級(jí)特大地震影響漂佩,放射性物質(zhì)發(fā)生泄漏脖含。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一投蝉、第九天 我趴在偏房一處隱蔽的房頂上張望养葵。 院中可真熱鬧,春花似錦瘩缆、人聲如沸关拒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽着绊。三九已至谐算,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間归露,已是汗流浹背洲脂。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剧包,地道東北人恐锦。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像疆液,于是被迫代替她去往敵國和親一铅。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359