日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

[改善Java代码]覆写equals方法必须覆写hashCode方法

發(fā)布時間:2025/3/15 java 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [改善Java代码]覆写equals方法必须覆写hashCode方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

覆寫equals方法必須覆寫hashCode方法,這條規(guī)則基本上每個Javaer都知道,這也是JDK API上反復(fù)說明的,不過為什么要這樣做呢?這兩個方法之間有什么關(guān)系呢?本建議就來解釋該問題,我們先來看如下代碼:

1 public static void main(String[] args) { 2 // Person類的實(shí)例作為Map的key 3 Map<Person, Object> map = new HashMap<Person, Object>() { 4 { 5 put(new Person("張三"), new Object()); 6 } 7 }; 8 // Person類的實(shí)例作為List的元素 9 List<Person> list = new ArrayList<Person>() { 10 { 11 add(new Person("張三")); 12 } 13 }; 14 // 列表中是否包含 15 boolean b1 = list.contains(new Person("張三")); 16 // Map中是否包含 17 boolean b2 = map.containsKey(new Person("張三")); 18 }

代碼中的Person類與上一建議相同(http://www.cnblogs.com/DreamDrive/p/5431603.html),euqals方法完美無缺。在這段代碼中,我們在聲明時直接調(diào)用方法賦值,這其實(shí)也是一個內(nèi)部匿名類的操作(下一個建議會詳細(xì)說明)。現(xiàn)在的問題是b1和b2這兩個boolean值是否都為true?

我們先來看b1,Person類的equals覆寫了,不再判斷兩個地址是否相等,而是根據(jù)人員的姓名來判斷兩個對象是否相等,所以不管我們的new Person(“張三”)產(chǎn)生了多少個對象,它們都是相等的。把“張三”對象放入List中,再檢查List中是否包含,那結(jié)果肯定是true了。

接著來看b2,我們把張三這個對象作為了Map的鍵(Key),放進(jìn)去的對象是張三,檢查的對象還是張三,那應(yīng)該和List的結(jié)果相同了,但是很遺憾,結(jié)果是false。原因何在呢?

原因就是HashMap的底層處理機(jī)制是以數(shù)組的方式保存Map條目(Map Entry)的,這其中的關(guān)鍵是這個數(shù)組下標(biāo)的處理機(jī)制:依據(jù)傳入元素hashCode方法的返回值決定其數(shù)組的下標(biāo),如果該數(shù)組位置上已經(jīng)有了Map條目,且與傳入的鍵值相等則不處理,若不相等則覆蓋;如果數(shù)組位置沒有條目,則插入,并加入到Map條目的鏈表中。同理,檢查鍵是否存在也是根據(jù)哈希碼確定位置,然后遍歷查找鍵值的。

接著深入探討,那對象元素的hashCode方法返回的是什么值呢?它是一個對象的哈希碼,是由Object類的本地方法生成的,確保每個對象有一個哈希碼(這也是哈希算法的基本要求:任意輸入k,通過一定算法f(k),將其轉(zhuǎn)換為非可逆的輸出,對于兩個輸入k1和k2,要求若k1=k2,則必須f(k1)=f(k2),但也允許k1≠k2,f(k1)=f(k2)的情況存在)。

那回到我們的例子上,由于我們沒有重寫hashCode方法,兩個張三對象的hashCode方法返回值(也就是哈希碼)肯定是不相同的了,在HashMap的數(shù)組中也就找不到對應(yīng)的Map條目了,于是就返回了false。

問題清楚了,修改也非常簡單,重寫一下hashCode方法即可,代碼如下:

class Person { /*其他代碼相同,不再贅述*/ @Override public int hashCode() { return new HashCodeBuilder().append(name).toHashCode(); } }

其中HashCodeBuilder是org.apache.commons.lang.builder包下的一個哈希碼生成工具,使用起來非常方便,諸位可以直接在項(xiàng)目中集成。(為什么不直接寫hashCode方法?因?yàn)楣4a的生成有很多種算法,自己寫麻煩,事兒又多,所以采用拿來主義是最好的方法。)

?

轉(zhuǎn)載于:https://www.cnblogs.com/DreamDrive/p/5431725.html

總結(jié)

以上是生活随笔為你收集整理的[改善Java代码]覆写equals方法必须覆写hashCode方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。