亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于HashSet與HashMap的區(qū)別及說(shuō)明

 更新時(shí)間:2023年07月26日 09:42:11   作者:huhahuha_  
這篇文章主要介紹了關(guān)于HashSet與HashMap的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

HashSet與HashMap的區(qū)別

HashSet 集合不允許存儲(chǔ)相同的元素, 它底層實(shí)際上使用 HashMap 來(lái)存儲(chǔ)元素的,不過(guò)關(guān)注的只是key元素, 所有 value元素默認(rèn)為 Object類(lèi)對(duì)象.

HashSet源碼如下

HashSet 的構(gòu)造方法

//HashSet底層用來(lái)存儲(chǔ)元素的結(jié)構(gòu),實(shí)際上使用HashMap來(lái)存儲(chǔ)
private transient HashMap<E,Object> map;
//HashMap中的value值,HashSet只關(guān)注key值,所以所有的value值都為Object對(duì)象
private static final Object PRESENT = new Object();
//HashSet的無(wú)參構(gòu)造,直接創(chuàng)建了一個(gè)HashMap對(duì)象
public HashSet() {
        map = new HashMap<>();
}
//指定初始化容量和負(fù)載因子
public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
}
//給定初始化容量
public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
}
public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
}

可以看到 HashSet的構(gòu)造方法底層都是調(diào)用 HashMap的構(gòu)造方法, 所以HashSet底層實(shí)際上是使用 HashMap 來(lái)作為存儲(chǔ)結(jié)構(gòu).

當(dāng)使用無(wú)參構(gòu)造創(chuàng)建 HashSet對(duì)象時(shí), 其實(shí)調(diào)用了 HashMap的無(wú)參構(gòu)造創(chuàng)建了一個(gè) HashMap對(duì)象, 所以 HashSet 的初始化容量也為16, 負(fù)載因子也為 0.75.

再來(lái)看看 HashSet 的 add() 方法的實(shí)現(xiàn):

可以看到 HashSet 的 add() 方法底層實(shí)際也是調(diào)用了 HashMap 的 put() 方法, 這里的key為我們傳入的將要添加到 set集合中的元素, 而value值則為 PERSENT,其實(shí)就是上面分析的 HashSet類(lèi)中的一個(gè)靜態(tài)字段, 默認(rèn)為 Object對(duì)象.

HashSet并不關(guān)注value元素, 只使用 HashMap來(lái)存儲(chǔ) key元素, 這就使得 HashSet判斷元素相等的條件與 HashMap中 key相等的條件其實(shí)是一樣的, 兩個(gè)元素的 hashCode值相同且通過(guò)equals()方法比較返回 true.

所以HashSet應(yīng)該重寫(xiě) equals()和hashCode()方法, 兩個(gè)元素的 HashCode相同, 保證通過(guò)equals() 方法比較返回 true.

總結(jié)一下HashSet和HashMap的區(qū)別

(1)HashSet實(shí)現(xiàn)了Set接口, 僅存儲(chǔ)對(duì)象; HashMap實(shí)現(xiàn)了 Map接口, 存儲(chǔ)的是鍵值對(duì).

(2)HashSet底層其實(shí)是用HashMap實(shí)現(xiàn)存儲(chǔ)的, HashSet封裝了一系列HashMap的方法. 依靠HashMap來(lái)存儲(chǔ)元素值,(利用hashMap的key鍵進(jìn)行存儲(chǔ)), 而value值默認(rèn)為Object對(duì)象. 所以HashSet也不允許出現(xiàn)重復(fù)值, 判斷標(biāo)準(zhǔn)和HashMap判斷標(biāo)準(zhǔn)相同, 兩個(gè)元素的hashCode相等并且通過(guò)equals()方法返回true.

HashSet與HashMap的關(guān)系

HashSet作為一種最簡(jiǎn)單的java集合類(lèi),真的可以用三句話來(lái)概括一下:

第一句:存放不重復(fù)的數(shù)據(jù)。第二句:底層基于hash表實(shí)現(xiàn)。第三句:內(nèi)部基于HashMap。

這也就是說(shuō),你想要完完全全徹徹底底地把HashSet吃透,就一定要先吃透HashMap。這篇文章將帶著你從特點(diǎn)到存儲(chǔ),再到最后的實(shí)現(xiàn),從源碼角度來(lái)分析一下。

認(rèn)識(shí)

HashSet其實(shí)就是一個(gè)沒(méi)有重復(fù)數(shù)據(jù)的集合,基本用法很簡(jiǎn)單,我們直接給個(gè)例子。

以上只是列出了其最簡(jiǎn)單的用法。下面我們看看其繼承關(guān)系。

HashSet主要繼承了三個(gè)接口Serializable、Cloneable、Set,并且實(shí)現(xiàn)了抽象類(lèi)AbstractSet。

我們直接看看源碼:

學(xué)過(guò)HashMap的人應(yīng)該都知道HashMap實(shí)現(xiàn)的是Map接口,而HashSet是Set接口。

下面我們就從源碼的角度來(lái)分析一下HashSet。

源碼分析

1、參數(shù)變量

這里有個(gè)問(wèn)題,那就是既然HashSet只使用到了HashMap的key,為什么不使用null來(lái)充當(dāng)HashMap的value,而使用了PRESENT這個(gè)對(duì)象呢?

答:想要深入這個(gè)問(wèn)題,我們還需要深入到源碼中看看:

以上兩個(gè)是增刪方法,在add一個(gè)元素的時(shí)候,其實(shí)調(diào)用的就是map.put(e, PRESENT)==null,HashMap在put元素的時(shí)候會(huì)出現(xiàn)兩種情況:

情況一:put的元素是新的,那么map.put會(huì)發(fā)現(xiàn)key沒(méi)有,那么直接插入即可。return結(jié)果為true。

情況二:put的元素是舊的,那么map.put會(huì)發(fā)現(xiàn)key已有,則直接返回相應(yīng)的value,也就是PRESENT,PRESENT不等于null,return的也就是false了,表示HashSet插入失敗。如果我們這里使用null為map.put的參數(shù)呢?直接返回相應(yīng)的value,也就是null,這時(shí)候null==null是true。竟然返回了true。很明顯就是錯(cuò)誤的返回結(jié)果呀。

這其實(shí)也是去重復(fù)的原理。對(duì)于刪除方法其實(shí)也是一樣的。

2、構(gòu)造函數(shù)

HashSet提供的構(gòu)造方法很多,有5個(gè),在這里我想說(shuō)明的是每一種構(gòu)造方法,其實(shí)都是創(chuàng)建的HashMap。這也證明了我們文章開(kāi)頭提到的內(nèi)部基于HashMap。

3、其他方法

增刪方法我們已經(jīng)提到了,在這里我們主要看一下其他方法。

上面的方法還包含了遍歷元素的方式。

HashSet就是這么簡(jiǎn)單,源碼里面幾乎所有的方法都是HashMap實(shí)現(xiàn)的。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java多線程中Lock的使用小結(jié)

    Java多線程中Lock的使用小結(jié)

    jdk1.5 以后,提供了各種鎖,本文主要介紹了Java多線程中Lock的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫(kù)管理的操作方法

    SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫(kù)管理的操作方法

    Flyway是一個(gè)開(kāi)源的數(shù)據(jù)庫(kù)版本管理工具,并且極力主張“約定大于配置”,簡(jiǎn)單、專(zhuān)注、強(qiáng)大。接下來(lái)通過(guò)本文給大家介紹SpringBoot使用Flyway進(jìn)行數(shù)據(jù)庫(kù)管理的方法,感興趣的朋友一起看看吧
    2021-09-09
  • SpringBoot工程Docker多環(huán)境中使用同一個(gè)Jar包解決方案

    SpringBoot工程Docker多環(huán)境中使用同一個(gè)Jar包解決方案

    在Docker多環(huán)境部署中,SpringBoot工程可以通過(guò)環(huán)境變量來(lái)動(dòng)態(tài)改變配置,無(wú)需重新打包,利用volume掛載或docker?cp命令,可以將配置文件直接傳入容器,提高部署效率,并保證安全性
    2024-09-09
  • java基礎(chǔ)之Object類(lèi)

    java基礎(chǔ)之Object類(lèi)

    這篇文章主要介紹了java基礎(chǔ)之Object類(lèi) 的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • Maven中的SnapShot版本和正式版本的區(qū)別

    Maven中的SnapShot版本和正式版本的區(qū)別

    在Nexus倉(cāng)庫(kù)中,一個(gè)倉(cāng)庫(kù)一般分為public(Release)倉(cāng)和SNAPSHOT倉(cāng),本文詳細(xì)的介紹了SnapShot版本和正式版本的區(qū)別,感興趣的可以了解一下
    2021-06-06
  • 解決ObjectMapper序列換Map時(shí)候的坑

    解決ObjectMapper序列換Map時(shí)候的坑

    這篇文章主要介紹了解決ObjectMapper序列換Map時(shí)候的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲(chǔ)詳解

    java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲(chǔ)詳解

    在本篇文章中小編給大家分享了關(guān)于java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲(chǔ)的相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-04-04
  • Java實(shí)現(xiàn)對(duì)華北、華南、華東和華中四個(gè)區(qū)域的劃分

    Java實(shí)現(xiàn)對(duì)華北、華南、華東和華中四個(gè)區(qū)域的劃分

    在Java中,通過(guò)定義枚舉類(lèi)、編寫(xiě)主程序和進(jìn)行測(cè)試,本文詳細(xì)介紹了如何劃分華北、華南、華東和華中四個(gè)區(qū)域,首先定義枚舉類(lèi)標(biāo)識(shí)區(qū)域,然后通過(guò)主程序接收用戶(hù)輸入并返回相應(yīng)區(qū)域,最后通過(guò)測(cè)試用例確保正確性,文章還介紹了甘特圖和餅狀圖的使用
    2024-09-09
  • 一文帶你掌握springBoot如何做到優(yōu)雅停機(jī)的

    一文帶你掌握springBoot如何做到優(yōu)雅停機(jī)的

    在分布式系統(tǒng)中,服務(wù)的優(yōu)雅停機(jī)(Graceful Shutdown)是確保業(yè)務(wù)連續(xù)性的重要機(jī)制,下面就跟隨小編一起來(lái)深入了解下springBoot實(shí)現(xiàn)優(yōu)雅停機(jī)的具體方式吧
    2025-04-04
  • Struts和servlet不能共存問(wèn)題解決方法

    Struts和servlet不能共存問(wèn)題解決方法

    這篇文章主要介紹了Struts和servlet不能共存問(wèn)題解決方法,共有三種方法,需要的朋友可以參考下。
    2017-09-09

最新評(píng)論