java equal hashcode_Java(二)equal 和 hashcode使用
一、hashCode()和equals()是什么?
hashCode()方法和equals()方法的作用其實(shí)一樣,在Java里都是用來對(duì)比兩個(gè)對(duì)象是否相等一致。
Equal
沒有重寫的equal 使用是繼承自 Object 的 equal 方法,和 “==” 的作用一樣, 比較兩個(gè)對(duì)象的內(nèi)存地址是否相等。
public boolean equals(Object obj) {
return (this == obj);
}
重寫過的 equal, 比較的是兩個(gè)對(duì)象的屬性變量值 是否相等。
HashCode
hashCode是對(duì)象在內(nèi)存地址通過hash算法得到的哈希碼。
二、hashCode()和equals()的區(qū)別
下邊從兩個(gè)角度介紹了他們的區(qū)別:一個(gè)是性能,一個(gè)是可靠性。他們之間的主要區(qū)別也基本體現(xiàn)在這里。
1、equals()既然已經(jīng)能實(shí)現(xiàn)對(duì)比的功能了,為什么還要hashCode()呢?
因?yàn)橹貙懙膃quals()里一般比較的比較全面比較復(fù)雜,這樣效率就比較低,而利用hashCode()進(jìn)行對(duì)比,則只要生成一個(gè)hash值進(jìn)行比較就可以了,效率很高。
2、hashCode()既然效率這么高為什么還要equals()呢?
因?yàn)閔ashCode()并不是完全可靠,有時(shí)候不同的對(duì)象他們生成的hashcode也會(huì)一樣(生成hash值得公式可能存在的問題),所以hashCode()只能說是大部分時(shí)候可靠,并不是絕對(duì)可靠,所以我們可以得出(PS:以下兩條結(jié)論是重點(diǎn),很多人面試的時(shí)候都說不出來):
equals()相等的兩個(gè)對(duì)象他們的hashCode()肯定相等,也就是用equals()對(duì)比是絕對(duì)可靠的。
hashCode()相等的兩個(gè)對(duì)象他們的equals()不一定相等,也就是hashCode()不是絕對(duì)可靠的。
三、hashCode()和equals()使用的注意事項(xiàng)
1、對(duì)于需要大量并且快速的對(duì)比的話如果都用equals()去做顯然效率太低,所以解決方式是,每當(dāng)需要對(duì)比的時(shí)候,首先用hashCode()去對(duì)比,如果hashCode()不一樣,則表示這兩個(gè)對(duì)象肯定不相等(也就是不必再用equals()去再對(duì)比
了),如果hashCode()相同,此時(shí)再對(duì)比他們的equals(),如果equals()也相同,則表示這兩個(gè)對(duì)象是真的相同了,這樣既能大大提高了效率也保證了對(duì)比的絕對(duì)正確性!
2、這種大量的并且快速的對(duì)象對(duì)比一般使用的hash容器中,比如HashSet,HashMap,HashTable等等,比如HashSet里要求對(duì)象不能重復(fù),則他內(nèi)部必然要對(duì)添加進(jìn)去的每個(gè)對(duì)象進(jìn)行對(duì)比,而他的對(duì)比規(guī)則就是像上面說的那樣,先hashCode(),如果hashCode()相同,再用equals()驗(yàn)證,如果hashCode()都不同,則肯定不同,這樣對(duì)比的效率就很高了。
3、然而hashCode()和equals()一樣都是基本類Object里的方法,而和equals()一樣,Object里hashCode()里面只是返回當(dāng)前對(duì)象的地址,如果是這樣的話,那么我們相同的一個(gè)類,new兩個(gè)對(duì)象,由于他們?cè)趦?nèi)存里的地址不同,則他們的
hashCode()不同,所以這顯然不是我們想要的,所以我們必須重寫我們類的hashCode()方法,即一個(gè)類,在hashCode()里面返回唯一的一個(gè)hash值,比如下面:
由于標(biāo)識(shí)這個(gè)類的是他的內(nèi)部的變量num和name,所以我們就根據(jù)他們返回一個(gè)hash值,作為這個(gè)類的唯一hash值。
所以如果我們的對(duì)象要想放進(jìn)hashSet,并且發(fā)揮hashSet的特性(即不包含一樣的對(duì)象),則我們就要重寫我們類的hashCode()和equals()方法了。像String,Integer等這種類內(nèi)部都已經(jīng)重寫了這兩個(gè)方法。
當(dāng)然如果我們只是平時(shí)想對(duì)比兩個(gè)對(duì)象 是否一致,則只重寫一個(gè)equals(),然后利用equals()去對(duì)比也行的
4、什么時(shí)候需要重寫?
一般的地方不需要重載hashCode,只有當(dāng)類需要放在HashTable、HashMap、HashSet等等hash結(jié)構(gòu)的集合時(shí)才會(huì)重載hashCode。
5、那么為什么要重載hashCode呢?
如果你重寫了equals,比如說是基于對(duì)象的內(nèi)容實(shí)現(xiàn)的,而保留hashCode的實(shí)現(xiàn)不變,那么很可能某兩個(gè)對(duì)象明明是“相等”,而hashCode卻不一樣。
這樣,當(dāng)你用其中的一個(gè)作為鍵保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一個(gè)作為鍵值去查找他們的時(shí)候,則根本找不到。
6、為什么equals()相等,hashCode就一定要相等,而hashCode相等,卻不要求equals相等?
因?yàn)槭前凑説ashCode來訪問小內(nèi)存塊,所以hashCode必須相等。
HashMap獲取一個(gè)對(duì)象是比較key的hashCode相等和equals為true。
之所以hashCode相等,卻可以equal不等,就比如ObjectA和ObjectB他們都有屬性name,那么hashCode都以name計(jì)算,所以hashCode一樣,但是兩個(gè)對(duì)象屬于不同類型,所以equals為false。
7、為什么需要hashCode?
通過hashCode可以很快的查到小內(nèi)存塊。
通過hashCode比較比equals方法快,當(dāng)get時(shí)先比較hashCode,如果hashCode不同,直接返回false。
------------------------------------------
總結(jié)
以上是生活随笔為你收集整理的java equal hashcode_Java(二)equal 和 hashcode使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A2的纸张是大的尺寸?谢谢!
- 下一篇: 判开头的成语有哪些啊?