自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

開發(fā) 后端
Set集合常用于元素為數(shù)字、字符串去重等,但是當(dāng)元素為自定義對(duì)象類型時(shí),Set去重是否與我們預(yù)計(jì)一致?下面將以HashSet為例,通過一系列試驗(yàn)來一步步驗(yàn)證。

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

[[282768]]

1. 先建立一個(gè)FootBallPlayer足球運(yùn)動(dòng)員類

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

結(jié)果:HashSet并沒有認(rèn)定兩個(gè)“C羅”對(duì)象重復(fù),三個(gè)實(shí)例都加入到了HashSet集合中。

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

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

6. 了解了兩個(gè)判斷條件后,我們先做一個(gè)簡(jiǎn)單實(shí)驗(yàn),既調(diào)用Integer 、String 、Object等對(duì)象equals()方法進(jìn)行對(duì)比

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

 

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

 

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

 

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

 

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

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

9. 重寫完方法,我們?cè)僦匦聢?zhí)行一開始的程序,還是同樣的三個(gè)足球運(yùn)動(dòng)員實(shí)例。結(jié)果與期望相同,HashSet對(duì)“C羅”對(duì)象進(jìn)行了去重處理。

Java中HashSet集合是如何對(duì)自定義對(duì)象進(jìn)行去重

總結(jié)

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

責(zé)任編輯:趙寧寧 來源: 今日頭條
相關(guān)推薦

2014-04-02 13:27:29

iOSNSArray對(duì)象

2010-03-01 11:10:41

WCF綁定元素

2022-04-14 15:12:40

Java8Stream列表

2010-05-05 14:34:45

Oracle數(shù)據(jù)庫(kù)

2009-08-04 13:31:35

C#自定義事件

2009-08-03 16:37:49

C#異常類

2021-12-15 06:58:13

List 集合LinkedHashS

2024-01-05 15:28:06

鴻蒙數(shù)據(jù)同步GlobalThis

2023-12-05 07:59:08

JS小技巧數(shù)組對(duì)象去重

2011-08-09 17:16:56

CoreAnimati動(dòng)畫

2009-11-09 16:06:53

WCF自定義集合

2021-11-23 15:06:42

Kubernetes 運(yùn)維開源

2021-03-16 10:39:29

SpringBoot參數(shù)解析器

2019-08-19 13:40:34

Windows 10剪貼板Windows

2022-07-06 07:35:19

group byMySQL

2011-12-16 14:23:51

Java

2011-06-15 09:24:36

Qt Widget Model

2009-09-07 22:00:15

LINQ自定義

2022-09-20 07:01:50

對(duì)象初始化代碼

2009-11-12 16:14:28

ADO.NET自定義對(duì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)