摘要:我們使用調(diào)試器卻發(fā)現(xiàn)在中已經(jīng)存儲(chǔ)了這個(gè)對(duì)象。中和有一個(gè)契約如果兩個(gè)對(duì)象相等的話,它們的必須相等但如果兩個(gè)對(duì)象的相等的話,這兩個(gè)對(duì)象不一定相等。的結(jié)構(gòu)能夠快速找到一個(gè)對(duì)象,而不是進(jìn)行較慢的線性查找??梢钥醋魇菙?shù)組的數(shù)組。
java.lang.Object類中有兩個(gè)非常重要的方法:
public boolean equals(Object obj) public int hashCode()
理解這兩個(gè)方法非常的重要,尤其是將用戶自定義的對(duì)象添加到Map中的時(shí)候。有時(shí)候就算是久經(jīng)沙場的老程序員也弄不清楚該如何正確使用它們。這篇文章中,我將用一個(gè)例子讓大家看看大家經(jīng)常會(huì)犯的錯(cuò)誤,然后解釋equals()和hashCode()的正確的使用方法。
常見的錯(cuò)誤如下:
import java.util.HashMap; public class Apple { private String color; public Apple(String color) { this.color = color; } public boolean equals(Object obj) { if (!(obj instanceof Apple)) return false; if (obj == this) return true; return this.color == ((Apple) obj).color; } public static void main(String[] args) { Apple a1 = new Apple("green"); Apple a2 = new Apple("red"); //hashMap stores apple type and its quantity HashMap m = new HashMap(); m.put(a1, 10); m.put(a2, 20); System.out.println(m.get(new Apple("green"))); } }
這個(gè)例子中,一個(gè)“綠蘋果”的對(duì)象成功添加到hashMap中了,但是當(dāng)我們要取出這個(gè)“綠蘋果”的時(shí)候,卻得不到這個(gè)對(duì)象,程序返回null。我們使用調(diào)試器卻發(fā)現(xiàn)在hashMap中已經(jīng)存儲(chǔ)了這個(gè)對(duì)象。
這個(gè)問題是因?yàn)椤県ashCode()”方法沒有被重寫。Java中equals()和hashCode()有一個(gè)契約:
如果兩個(gè)對(duì)象相等的話,它們的hash code必須相等;
但如果兩個(gè)對(duì)象的hash code相等的話,這兩個(gè)對(duì)象不一定相等。
Map的結(jié)構(gòu)能夠快速找到一個(gè)對(duì)象,而不是進(jìn)行較慢的線性查找。使用hash過的鍵來定位對(duì)象分兩步。Map可以看作是數(shù)組的數(shù)組。第一個(gè)數(shù)組的索引就是對(duì)鍵采用hashCode()計(jì)算出來的值,再在這個(gè)位置上查找第二個(gè)數(shù)組,使用鍵的equals()方法來進(jìn)行線性查找,直到找到要找的對(duì)象。
Object類中的hashCode()對(duì)于不同的對(duì)象返回不同的整數(shù),所以上面的例子中,不同的對(duì)象(即使相同的類型)也返回不同的hash值。
Hash碼就像是一個(gè)存儲(chǔ)空間的序列,不同的東西放在不同的存儲(chǔ)空間中。將不同的東西整理放在不同的空間中(而不是堆積在一個(gè)空間中)更高效。所以能夠均勻的分散hash碼是再好不過了。
上面錯(cuò)誤的解決方法就是在類中增加hashCode方法。這里我僅僅使用顏色的長度來計(jì)算hash碼。
public int hashCode(){ return this.color.length(); }
原文:Java equals() and hashCode() Contract
翻譯:ImportNew.com - 唐小娟
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64050.html
摘要:抽象函數(shù)引發(fā)的關(guān)系是等價(jià)關(guān)系。所以當(dāng)且僅當(dāng)通過調(diào)用抽象數(shù)據(jù)類型的任何操作不能區(qū)分它們時(shí),兩個(gè)對(duì)象是相等的。必須為每個(gè)抽象數(shù)據(jù)類型適當(dāng)?shù)囟x操作。一般來說,在面向?qū)ο缶幊讨惺褂檬且环N陋習(xí)。 大綱 什么是等價(jià)性?為什么要討論等價(jià)性?三種等價(jià)性的方式==與equals()不可變類型的等價(jià)性對(duì)象契約可變類型的等價(jià)性自動(dòng)包裝和等價(jià)性 什么是等價(jià)性?為什么要討論等價(jià)性? ADT上的相等操作 ADT...
對(duì)象排序 List l可以如下排序。 Collections.sort(l); 如果List包含String元素,它將按字母順序排序,如果它由Date元素組成,它將按時(shí)間順序排序,這是怎么發(fā)生的?String和Date都實(shí)現(xiàn)了Comparable接口,Comparable實(shí)現(xiàn)為類提供了自然的順序,允許該類的對(duì)象自動(dòng)排序,下表總結(jié)了一些實(shí)現(xiàn)Comparable的更重要的Java平臺(tái)類。 類 自然...
摘要:程序失敗時(shí),很難確定錯(cuò)誤的位置。它保護(hù)客戶免受單位工作細(xì)節(jié)的影響。將前提條件放在中,并將后置條件放入和。涉及可變對(duì)象的契約現(xiàn)在取決于每個(gè)引用可變對(duì)象的每個(gè)人的良好行為。設(shè)計(jì)規(guī)約按規(guī)約分類比較規(guī)約它是如何確定性的。 大綱 1.編程語言中的功能/方法2.規(guī)約:便于交流的編程,為什么需要規(guī)約 行為等同規(guī)約結(jié)構(gòu):前提條件和后條件測試和驗(yàn)證規(guī)約3.設(shè)計(jì)規(guī)約分類規(guī)約圖表規(guī)約質(zhì)量規(guī)約4.總結(jié) 編程...
摘要:如果根據(jù)方法得到兩個(gè)對(duì)象不相同,那么兩個(gè)對(duì)象的方法的結(jié)果不一定不相同,我們可以利用這一點(diǎn)來提高散列表的性能。最后回到文章開頭的問題,如何判斷兩個(gè)對(duì)象或值是否相同這個(gè)問題其實(shí)有兩方面的含義,一方面是判斷的方法,另一方面是判斷的效率。 Java中有很多場景需要判斷兩個(gè)對(duì)象或者兩個(gè)值,那么 判斷是否相同的依據(jù)是什么? 如何判斷是否相同呢? 為了解釋這個(gè)問題,我們從Java語言的根說起,那...
摘要:相關(guān)的文章網(wǎng)上很多了寫這個(gè)主要是按自己的思路進(jìn)行記錄是什么中的實(shí)現(xiàn)是一個(gè)本地方法生成一個(gè)表征當(dāng)前對(duì)象實(shí)例的特征值具體的實(shí)現(xiàn)根據(jù)的實(shí)現(xiàn)可能會(huì)不同中實(shí)際計(jì)算的函數(shù)的實(shí)現(xiàn)如下為時(shí)是直接使用的內(nèi)存地址但默認(rèn)使用的是的隨 hashcode相關(guān)的文章網(wǎng)上很多了, 寫這個(gè)主要是按自己的思路進(jìn)行記錄 hashCode是什么 Object中的hashCode實(shí)現(xiàn)是一個(gè)本地方法, 生成一個(gè)表征當(dāng)前對(duì)象實(shí)例...
閱讀 2940·2021-11-04 16:06
閱讀 775·2021-09-30 09:56
閱讀 1841·2021-09-22 10:02
閱讀 2622·2019-08-29 13:43
閱讀 2218·2019-08-29 13:42
閱讀 2300·2019-08-29 12:21
閱讀 1056·2019-08-29 11:29
閱讀 1387·2019-08-26 13:51