日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Java中HashSet集合是如何對自定義對象進行去重

Java中Set接口是Collectio的子接口,Set集合不允許包含相同的元素。如果添加相同的元素, add()會返回FALSE, 新元素不會加入。Set集合常用于元素為數(shù)字、字符串去重等,但是當元素為自定義對象類型時,Set去重是否與我們預計一致?下面將以HashSet為例,通過一系列試驗來一步步驗證。

成都創(chuàng)新互聯(lián)公司秉承實現(xiàn)全網(wǎng)價值營銷的理念,以專業(yè)定制企業(yè)官網(wǎng),網(wǎng)站建設、網(wǎng)站設計,重慶小程序開發(fā)公司,網(wǎng)頁設計制作,成都做手機網(wǎng)站,成都全網(wǎng)營銷推廣幫助傳統(tǒng)企業(yè)實現(xiàn)“互聯(lián)網(wǎng)+”轉(zhuǎn)型升級專業(yè)定制企業(yè)官網(wǎng),公司注重人才、技術(shù)和管理,匯聚了一批優(yōu)秀的互聯(lián)網(wǎng)技術(shù)人才,對客戶都以感恩的心態(tài)奉獻自己的專業(yè)和所長。

1. 先建立一個FootBallPlayer足球運動員類

2. (假設:HashSet會把屬性值全相同的對象認定為重復),為了測試HashSet對對象去重效果與猜想是否一致,我們先構(gòu)建三個對象實例,其中構(gòu)造兩個屬性一致的“C羅”。

結(jié)果:HashSet并沒有認定兩個“C羅”對象重復,三個實例都加入到了HashSet集合中。

3. 在了解HashSet如何進行去重之前,先看看HashSet是怎么實現(xiàn)的。通過查看JDK源碼發(fā)現(xiàn)HashSet內(nèi)部其實是對HashMap進行操作。

4. 繼續(xù)查看hashSet的add()方法,其實是調(diào)用了HashMap的put()方法

5. 繼續(xù)追蹤,直到putVal()方法(重點)

仔細看putVal()方法,發(fā)現(xiàn)其對于新入的元素是否重復判斷依據(jù)為以下兩種

  • 判斷hash值是否相等,既通過判斷hashCode()方法
  • 判斷是否相等,通過equals()方法

6. 了解了兩個判斷條件后,我們先做一個簡單實驗,既調(diào)用Integer 、String 、Object等對象equals()方法進行對比

結(jié)果發(fā)現(xiàn),自定義Object對象equals返回的值為false。接下來我們逐一看看它們的equals實現(xiàn)方式

(1) Integer對象的equals實現(xiàn),通過閱讀代碼發(fā)現(xiàn)是判斷依據(jù)是值是否相等。

(2) String對象的equals實現(xiàn),其判斷的依據(jù)為:先判斷引用的對象是否是同一個,再逐個對比其字符串的值

(3)  而Object的判斷依據(jù)為引用的對象是否是同一個,由于上面的兩位足球運動員都是新new出來的,非同一個對象,所以equlas()返回結(jié)果為false

7. 看完了equlas的實現(xiàn),接下來看看Integer String Object的hashCode實現(xiàn)。同樣先做一個簡單的測試,調(diào)用它們的hashCode()方法計算出hash值進行對比

實驗為結(jié)果兩個Object對象的hash值并不相等,接下來我們看看它們對于hashcode()的具體實現(xiàn)

(1) 通過源碼發(fā)現(xiàn) Integer是通過對其value值來進運算行得到hash值。

(2) String也是通過對其value值來進計算行得到hash值,所以測試中結(jié)果為true

(3) 當查看Object的hashCode()方法時發(fā)現(xiàn)并無具體實現(xiàn),通過查閱資料得知,JDK8的默認hashCode的計算是交給C++實現(xiàn)的,方法是通過和當前線程有關(guān)的一個隨機數(shù)+三個確定值,運用Marsaglia's

xorshifschema隨機數(shù)算法得到的一個隨機數(shù)。所以兩個不同的對象得到的hash值便不相同,測試結(jié)果也為false。(對于Object的hashCode()這里不做深入討論,如果過深入了解的朋友也歡迎分享)

8. 得知了HashSet是通過hashcode()與equals()來進行去重,且自定義Object對象的equals()和hashcode()實現(xiàn)原理,那么要實現(xiàn)HashSet按照我們期望的方式,當兩個對象所有屬性的值一致時認定為同一個對象,我們可以對FootBallPlayer類的equals()和hashcode()進行重寫,代碼如下

  • hashCode() 重寫為hash值是通過對對象所有屬性的值進行運算得出。
  • equals() 重寫為先判斷引用的對象是否是同一個,再判斷對象每一個屬性值是否相等

9. 重寫完方法,我們再重新執(zhí)行一開始的程序,還是同樣的三個足球運動員實例。結(jié)果與期望相同,HashSet對“C羅”對象進行了去重處理。

總結(jié)

HashSet的底層是對HashMap的操作,其去重的原理通過hashCode()與equals()方法來判斷是否重復。通過實驗發(fā)現(xiàn)自定義對象沒有成功去重的原因與JDK默認的Object對象hashCode()和equals()實現(xiàn)有關(guān)。對于自定義對象的去重,我們可以通過重寫自定義對象的hashCode()與equals()使其按照我們所想要的規(guī)則進行去重操作。


新聞名稱:Java中HashSet集合是如何對自定義對象進行去重
文章地址:http://www.dlmjj.cn/article/djoidej.html