成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中HashSet集合是如何對自定義對象進行去重

開發 后端
Set集合常用于元素為數字、字符串去重等,但是當元素為自定義對象類型時,Set去重是否與我們預計一致?下面將以HashSet為例,通過一系列試驗來一步步驗證。

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

[[282768]]

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

Java中HashSet集合是如何對自定義對象進行去重

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

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

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

Java中HashSet集合是如何對自定義對象進行去重

結果發現,自定義Object對象equals返回的值為false。接下來我們逐一看看它們的equals實現方式

Java中HashSet集合是如何對自定義對象進行去重

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

 

Java中HashSet集合是如何對自定義對象進行去重

 

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

 

Java中HashSet集合是如何對自定義對象進行去重

 

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

Java中HashSet集合是如何對自定義對象進行去重

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

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

Java中HashSet集合是如何對自定義對象進行去重

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

Java中HashSet集合是如何對自定義對象進行去重

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

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

Java中HashSet集合是如何對自定義對象進行去重

總結

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

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2014-04-02 13:27:29

iOSNSArray對象

2010-03-01 11:10:41

WCF綁定元素

2022-04-14 15:12:40

Java8Stream列表

2021-12-15 06:58:13

List 集合LinkedHashS

2023-12-05 07:59:08

JS小技巧數組對象去重

2010-05-05 14:34:45

Oracle數據庫

2013-06-27 11:10:01

iOS開發自定義UISlider

2019-08-19 13:40:34

Windows 10剪貼板Windows

2009-08-04 13:31:35

C#自定義事件

2009-08-03 16:37:49

C#異常類

2024-01-05 15:28:06

鴻蒙數據同步GlobalThis

2009-11-09 16:06:53

WCF自定義集合

2011-08-09 17:16:56

CoreAnimati動畫

2021-11-23 15:06:42

Kubernetes 運維開源

2022-07-06 07:35:19

group byMySQL

2019-12-02 21:29:45

Keras神經網絡TensorFlow

2011-09-05 18:54:03

windowsUbuntu

2021-07-01 11:07:49

Swift 自定義操作符

2010-02-07 14:02:16

Android 界面

2022-06-06 09:01:16

SwiftUI自定義導航
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品在线观看网站 | 精品视频在线一区 | 久久99精品久久久久久青青日本 | 欧美性生活一区二区三区 | 日韩久久久久 | 国产乱码久久久久久 | 中文二区 | 亚洲激情第一页 | 可以免费观看的av片 | 久久久123| 亚洲国产精品一区二区www | 日韩av一区二区在线观看 | 超碰人人做 | 一区二区三区在线播放 | 中文字幕乱码一区二区三区 | 草b视频 | 日韩视频在线免费观看 | 精品久久久网站 | 亚洲久草视频 | 国产精品成人一区二区 | 一区二区三区av夏目彩春 | 国产成人综合一区二区三区 | 日日草夜夜草 | 99精品九九 | 国产精品久久国产精品99 | 国产精品久久久久久久久久免费看 | 欧美成人一区二免费视频软件 | 在线午夜 | 三级高清 | 国产精品伦一区二区三级视频 | a免费视频| 中文字幕一区二区三区四区五区 | 欧美日韩国产一区二区三区 | 国产专区免费 | 精国产品一区二区三区四季综 | 99精品欧美一区二区三区综合在线 | 51ⅴ精品国产91久久久久久 | 欧美国产91 | h漫在线观看 | 国产精品久久国产精品 | 亚洲欧美成人在线 |