hashCode之一--两个对象值相同,有相同的hash code
兩個對象值相同(x.equals(y) == true),則一定有相同的hash code。
?
這是java語言的定義:?
因為:Hash,一般翻譯做“散列”,也有直接音譯為"哈希"的,就是把任意長度的輸入(又叫做預(yù)映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。
1) 對象相等則hashCode一定相等;
2) hashCode相等對象未必相等。(不同對象的hashcode是否一定不一樣?是錯誤的,hashcode本身就是個函數(shù),是可以重載的,你完全可以寫個函數(shù)總是返回固定值。但hashcode函數(shù)從設(shè)計要求上來說,要盡量保證:不同對象的hashcode不同。)
這也涉及到如何寫自定義的hashCode方法的問題:必須符合以上條件。注意條件2中的未必。具體可參見java doc; Effective Java中有更詳細論述
本貼來自ZDNetChina中文社區(qū)?http://bbs.zdnet.com.cn?,本貼地址:http://bbs.zdnet.com.cn/viewthread.php?tid=362649
?
== 是比較地址是否相等,JAVA中聲明變量都是引用嘛,不同的引用,可能指向同一個地址。
equals 是比較值是否相等。
這種題很容易在面試中被問到。。。
?
hash code、equals和“==”三者的關(guān)系
?
1.如果是基本變量,沒有hashcode和equals方法,基本變量的比較方式就只有==,;
2.如果是變量,由于在java中所有變量定義都是一個指向?qū)嶋H存儲的一個句柄(你可以理解為c++中的指針),在這里==是比較句柄的地址(你可以理解為指針的存儲地址),而不是句柄指向的實際內(nèi)存中的內(nèi)容,如果要比較實際內(nèi)存中的內(nèi)容,那就要用equals方法,但是!!!
如果是你自己定義的一個類,比較自定義類用equals和==是一樣的,都是比較句柄地址,因為自定義的類是繼承于object,而object中的equals就是用==來實現(xiàn)的,你可以看源碼。
那為什么我們用的String等等類型equals是比較實際內(nèi)容呢,是因為String等常用類已經(jīng)重寫了object中的equals方法,讓equals來比較實際內(nèi)容,你也可以看源碼。
3. hashcode
在一般的應(yīng)用中你不需要了解hashcode的用法,但當你用到hashmap,hashset等集合類時要注意下hashcode。
你想通過一個object的key來拿hashmap的value,hashmap的工作方法是,通過你傳入的object的hashcode在內(nèi)存中找地址,當找到這個地址后再通過equals方法來比較這個地址中的內(nèi)容是否和你原來放進去的一樣,一樣就取出value。
所以這里要匹配2部分,hashcode和equals
但假如說你new一個object作為key去拿value是永遠得不到結(jié)果的,因為每次new一個object,這個object的hashcode是永遠不同的,所以我們要重寫hashcode,你可以令你的hashcode是object中的一個恒量,這樣永遠可以通過你的object的hashcode來找到key的地址,然后你要重寫你的equals方法,使內(nèi)存中的內(nèi)容也相等。。。
?
?
首先,從語法角度,也就是從強制性的角度來說,hashCode和equals是兩個獨立的,互不隸屬,互不依賴的方法,equals成立與hashCode相等這兩個命題之間,誰也不是誰的充分條件或者必要條件。 ?
???
??但是,從為了讓我們的程序正常運行的角度,我們應(yīng)當向Effective ??Java中所言 ?
???
??重載equals的時候,一定要(正確)重載hashCode ?
???
??使得equals成立的時候,hashCode相等,也就是a.equals(b)->a.hashCode() ??== ??b.hashCode(),或者說此時,equals是hashCode相等的充分條件,hashCode相等是equals的必要條件(從數(shù)學(xué)課上我們知道它的逆否命題:hashCode不相等也不會equals),但是它的逆命題,hashCode相等一定equals以及否命題不equals時hashCode不等都不成立。 ?
???
??所以,如果面試的時候,最好把hashCode與equals之間沒有強制關(guān)系,以及根據(jù)(沒有語法約束力的)規(guī)范的角度,應(yīng)當做到...這兩層意思都說出來:P??
?
?
??總結(jié)一下,equals()是對象相等性比較,hashCode()是計算對象的散列值,當然他們的依據(jù)是對象的屬性。
?對于equals,一般我們認為兩個對象同類型并且所有屬性相等的時候才是相等的,在類中必須改寫equals,因為Object類中的equals只是判斷兩個引用變量是否引用同一對象,如果不是引用同一對象,即使兩個對象的內(nèi)容完全相同,也會返回false。當然,在類中改寫這個equals時,你也可以只對部分屬性進行比較,只要這些屬性相同就認為對象是相等的。 ?
???
??對于hashCode,只要是用在和哈希運算有關(guān)的地方,前面很多兄弟都提到了,和equals一樣,在你的類中也應(yīng)該改寫。當然如果兩個對象是完全相同的,那么他們的hashCode當然也是一樣的,但是象前面所述,規(guī)則可以由你自己來定義,因此兩者之間并沒有什么必然的聯(lián)系。 ?
???
??當然,大多數(shù)情況下我們還是根據(jù)所有的屬性來計算hashCode和進行相等性比較。
總結(jié)
以上是生活随笔為你收集整理的hashCode之一--两个对象值相同,有相同的hash code的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux中offsetof与conta
- 下一篇: killall