最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

HashSet與HashMap的區(qū)別

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

HashSet源碼如下

HashSet 的構(gòu)造方法

//HashSet底層用來存儲(chǔ)元素的結(jié)構(gòu),實(shí)際上使用HashMap來存儲(chǔ)
private transient HashMap<E,Object> map;
//HashMap中的value值,HashSet只關(guān)注key值,所以所有的value值都為Object對(duì)象
private static final Object PRESENT = new Object();
//HashSet的無參構(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 來作為存儲(chǔ)結(jié)構(gòu).

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

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

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

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

所以HashSet應(yīng)該重寫 equals()和hashCode()方法, 兩個(gè)元素的 HashCode相同, 保證通過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來存儲(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相等并且通過equals()方法返回true.

HashSet與HashMap的關(guān)系

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

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

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

認(rèn)識(shí)

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

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

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

我們直接看看源碼:

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

下面我們就從源碼的角度來分析一下HashSet。

源碼分析

1、參數(shù)變量

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

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

以上兩個(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沒有,那么直接插入即可。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è),在這里我想說明的是每一種構(gòu)造方法,其實(shí)都是創(chuàng)建的HashMap。這也證明了我們文章開頭提到的內(nèi)部基于HashMap。

3、其他方法

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

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

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

總結(jié)

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

相關(guān)文章

  • Spring Boot Jar 包部署腳本的實(shí)例講解

    Spring Boot Jar 包部署腳本的實(shí)例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Spring Boot Jar 包部署腳本的實(shí)例講解內(nèi)容,對(duì)此有興趣的朋友們可以跟著學(xué)習(xí)下。
    2021-12-12
  • JAVA隨機(jī)打亂數(shù)組順序的方法

    JAVA隨機(jī)打亂數(shù)組順序的方法

    這篇文章主要介紹了JAVA隨機(jī)打亂數(shù)組順序的方法,包含了隨機(jī)數(shù)的應(yīng)用及數(shù)組的排序等操作,是Java操作數(shù)組的典型應(yīng)用,需要的朋友可以參考下
    2014-11-11
  • 一文淺析SpringBoot3中的異步批量處理操作

    一文淺析SpringBoot3中的異步批量處理操作

    對(duì)于使用 Spring Boot 3 框架的開發(fā)者而言,掌握異步批量處理操作至關(guān)重要,本文將深入探討 Spring Boot 3 中異步批量處理操作的方方面面,幫助各位開發(fā)者在實(shí)際項(xiàng)目中更好地應(yīng)用這一強(qiáng)大功能
    2025-12-12
  • idea springboot遠(yuǎn)程debug的操作方法

    idea springboot遠(yuǎn)程debug的操作方法

    這篇文章主要介紹了idea springboot遠(yuǎn)程debug的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • JAVA開發(fā)環(huán)境Vs?code配置步驟詳解

    JAVA開發(fā)環(huán)境Vs?code配置步驟詳解

    這篇文章主要為大家介紹了JAVA開發(fā)環(huán)境Vs?code配置步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Java中串行接口調(diào)用優(yōu)化方式

    Java中串行接口調(diào)用優(yōu)化方式

    這篇文章主要介紹了Java中串行接口調(diào)用優(yōu)化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java解析xml匯總_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    java解析xml匯總_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了java解析xml匯總_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • HashMap原理及手寫實(shí)現(xiàn)部分區(qū)塊鏈特征

    HashMap原理及手寫實(shí)現(xiàn)部分區(qū)塊鏈特征

    這篇文章主要為大家介紹了HashMap原理及手寫實(shí)現(xiàn)部分區(qū)塊鏈特征,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java創(chuàng)建子線程的兩種方法

    Java創(chuàng)建子線程的兩種方法

    這篇文章主要介紹了Java創(chuàng)建子線程的兩種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java StackTraceElement實(shí)例代碼

    Java StackTraceElement實(shí)例代碼

    這篇文章主要介紹了Java StackTraceElement實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02

最新評(píng)論

开阳县| 博白县| 益阳市| 藁城市| 娱乐| 武胜县| 启东市| 明水县| 涿州市| 兴仁县| 东山县| 玛沁县| 涟源市| 澳门| 扎兰屯市| 芒康县| 巴彦县| 县级市| 涿州市| 会宁县| 大同市| 洪泽县| 高密市| 海口市| 巴塘县| 石棉县| 崇明县| 新竹县| 麻江县| 海阳市| 泗水县| 成安县| 新河县| 淳安县| 腾冲县| 鄂托克前旗| 鹤山市| 柳河县| 益阳市| 剑河县| 南部县|