我們知道,equals()函數(shù)是用來(lái)做比較的。java中的比較有兩種:一種是內(nèi)存地址的比較,一種是內(nèi)容的比較。而比較個(gè)體也有兩種:一種是簡(jiǎn)單類型(這類簡(jiǎn)單說(shuō)來(lái)無(wú)所謂內(nèi)存地址的比較或者內(nèi)容比較的區(qū)別);還有一種是對(duì)象的比較,本文中說(shuō)的主要是后者
在java中,(對(duì)象)內(nèi)存地址的比較,是通過(guò)==完成的。比如




這樣的語(yǔ)句中,我們認(rèn)為,如果obj1和obj2的內(nèi)存地址相同,則返回true
而equals()通常是比較內(nèi)容的。這里說(shuō)“通常” ,是因?yàn)樵谧罡镜腛bject類中,equal()函數(shù)做的是地址的比較。而在其他幾乎所有的類中,equals()都經(jīng)過(guò)重載,進(jìn)行內(nèi)容的比較。
而在說(shuō)equals()的時(shí)候我們還涉及hashCode()是因?yàn)樵谟行?yīng)用中(比如,HashMap的key是對(duì)象),必須在重載equals()的同時(shí)重載hashCode()。因?yàn)閖ava中默認(rèn)(Object)的hashCode是根據(jù)對(duì)象的地址計(jì)算得到的。
我們通常不會(huì)注意到這個(gè)問(wèn)題,因?yàn)槲覀兺ǔK褂玫?em>key都是簡(jiǎn)單類型,或者是String, Long等一些特殊的對(duì)象(其特殊性請(qǐng)參看筆者在寫java 淺拷貝和深拷貝時(shí)的討論),這時(shí)候,這個(gè)問(wèn)題被我們無(wú)意間繞過(guò)了
有人已經(jīng)概括了這種我們忽略了的情況:“如果你想將一個(gè)對(duì)象A放入另一個(gè)收集(集合)對(duì)象B里,或者使用這個(gè)對(duì)象A為查找一個(gè)元對(duì)象在收集對(duì) 象B里位置的鑰匙(key),并支持是否容納(isContains()),刪除收集對(duì)象B里的元對(duì)象(remove()?)這樣的操作,那么,equals()和hashCode()函數(shù)必須開發(fā)者自己定義。” (括號(hào)為筆者添加)
為了便于理解,舉一段程序?yàn)槔?/p>










































這段代碼的結(jié)果是什么?答案是nullPointerExcetpion.
而把hashCode()的注釋去除,程序就可以返回正確的結(jié)果了。為什么呢?因?yàn)椋?/p>
Map.put(key,value)時(shí)根據(jù)key.hashCode生成一個(gè)內(nèi)部hash值,根據(jù)這個(gè)hash值將對(duì)象存放在一個(gè)table中
Map.get(key)會(huì)比較key.hashCode和equals方法,當(dāng)且僅當(dāng)這兩者相等時(shí),才能正確定位到table。而我們說(shuō)過(guò),默認(rèn)的java是對(duì)地址進(jìn)行比較的。
對(duì)這句話還是不理解,能不能詳細(xì)的講講啊,謝謝!
Person value = (Person)map.get(p1);
這樣得到null吧