成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java容器類框架分析(5)HashSet源碼分析

wslongchen / 3302人閱讀

摘要:到此發(fā)現(xiàn),實(shí)際上可以拆分成跟指的是,則是指實(shí)現(xiàn)了接口,這樣看來,的實(shí)現(xiàn)其實(shí)就比較簡單了,下面開始分析源碼。

概述

在分析HashSet源碼前,先看看HashSet的繼承關(guān)系

HashSet繼承關(guān)系
從上圖可以看出,HashSet繼承自AbstractSet,實(shí)現(xiàn)了Set接口,接著看一下源碼中的注釋

This class implements the Set interface, backed by a hash table
(actually a HashMapinstance). It makes no guarantees as to the
iteration order of the set; in particular, it does not guarantee that the
order will remain constant over time. This class permits the null element.
HashSet實(shí)現(xiàn)了Set接口,內(nèi)部有一個哈希表支撐(實(shí)際上就是一個HashMap實(shí)例),它不保證迭代的順序;尤其是,隨著時間的變化,它不能保證set的迭代順序保持不變。允許插入空值。
到此發(fā)現(xiàn),HashSet實(shí)際上可以拆分成Hash跟Set,Hash指的是HashMap,Set則是指實(shí)現(xiàn)了Set接口,這樣看來,HashSet的實(shí)現(xiàn)其實(shí)就比較簡單了,下面開始分析源碼。

正文

成員變量

//序列化ID
 static final long serialVersionUID = -5024744406713321676L;
//內(nèi)置的HashMap
 private transient HashMap map;

 // 就是一個傀儡,填充HashMap的Value而已,沒有實(shí)際意義
 private static final Object PRESENT = new Object();

構(gòu)造方法

空的構(gòu)造方法

初始化一個空的HashMap

  public HashSet() {
        map = new HashMap<>();
    }

帶有容量的構(gòu)造方法

HashMap給定一個容量

public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

帶有容量跟負(fù)載因子的構(gòu)造方法

public HashSet(int initialCapacity, float loadFactor) {

    map = new HashMap<>(initialCapacity, loadFactor);
}

帶有容量跟負(fù)載因子,以及Value類型區(qū)分

dummy作為Value是基本類型跟引用類型,注意此處初始化的是一個LinkedHashMap

 HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

通過一個集合初始化

  public HashSet(Collection c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

調(diào)用addAll方法

   public boolean addAll(Collection c) {
        boolean modified = false;
        //循環(huán)遍歷
        for (E e : c)
        //如果set中沒有此元素,添加成功
            if (add(e))
                modified = true;
        return modified;
    }

增加元素

添加一個元素,如果Map中存在,返回false,否則返回true

 public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

看一下Map的put方法

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key);
        int i = indexFor(hash, table.length);
        for (HashMapEntry e = table[i]; e != null; e = e.next) {
            Object k;
        //這里比較了hash值跟equals方法
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

所以Set元素必須復(fù)寫hashcode跟equals方法,不然會導(dǎo)致元素錯亂

刪除元素

 public boolean remove(Object o) {
  //直接調(diào)用map的方法
        return map.remove(o)==PRESENT;
    }

clear

public void clear() {
//調(diào)用map的Clear方法

    map.clear();
}

contains方法

  public boolean contains(Object o) {
   調(diào)用map的contains方法
        return map.containsKey(o);
    }

isEmpty

 public boolean isEmpty() {
  //調(diào)用map的isEmpty方法
        return map.isEmpty();
    }

迭代

public Iterator iterator() {
//因?yàn)椴恍枰獀alue,所以只是調(diào)用了keySet的iterator

    return map.keySet().iterator();
}

分析了一下,其實(shí)最終的底層實(shí)現(xiàn)都是在調(diào)用HashMap的方法,所以了解了HashMap的源碼之后,HashSet其實(shí)就會比較簡單了
總結(jié)

HashSet是非線程安全的,允許插入空元素
HashSet不允許重復(fù)元素
HashSet的Key需要復(fù)寫hashcode跟equals方法

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67728.html

相關(guān)文章

  • [學(xué)習(xí)筆記-Java集合-9] Set - HashSet源碼分析

    摘要:源碼分析屬性內(nèi)部使用虛擬對象,用來作為放到中構(gòu)造方法非,主要是給使用的構(gòu)造方法都是調(diào)用對應(yīng)的構(gòu)造方法。遍歷元素直接調(diào)用的的迭代器。什么是機(jī)制是集合中的一種錯誤機(jī)制。當(dāng)使用迭代器迭代時,如果發(fā)現(xiàn)集合有修改,則快速失敗做出響應(yīng),拋出異常。 簡介 集合,這個概念有點(diǎn)模糊。 廣義上來講,java中的集合是指java.util包下面的容器類,包括和Collection及Map相關(guān)的所有類。 中...

    kohoh_ 評論0 收藏0
  • Java相關(guān)

    摘要:本文是作者自己對中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對之處,望指出,共勉。當(dāng)中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機(jī)制講得很透徹,深入淺出。 一小時搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個接口,程序可以通過...

    wangtdgoodluck 評論0 收藏0
  • 金三銀四,2019大廠Android高級工程師面試題整理

    摘要:原文地址游客前言金三銀四,很多同學(xué)心里大概都準(zhǔn)備著年后找工作或者跳槽。最近有很多同學(xué)都在交流群里求大廠面試題。 最近整理了一波面試題,包括安卓JAVA方面的,目前大廠還是以安卓源碼,算法,以及數(shù)據(jù)結(jié)構(gòu)為主,有一些中小型公司也會問到混合開發(fā)的知識,至于我為什么傾向于混合開發(fā),我的一句話就是走上編程之路,將來你要學(xué)不僅僅是這些,豐富自己方能與世接軌,做好全棧的裝備。 原文地址:游客kutd...

    tracymac7 評論0 收藏0
  • JDK源碼容器篇)

    摘要:三系列用于保存鍵值對,無論是,還是已棄用的或者線程安全的等,都是基于紅黑樹。是完全基于紅黑樹的,并在此基礎(chǔ)上實(shí)現(xiàn)了接口。可以看到,只有紅黑樹,且紅黑樹是通過內(nèi)部類來實(shí)現(xiàn)的。 JDK容器 前言 閱讀JDK源碼有段時間了,準(zhǔn)備以博客的形式記錄下來,也方便復(fù)習(xí)時查閱,本文參考JDK1.8源碼。 一、Collection Collection是所有容器的基類,定義了一些基礎(chǔ)方法。List、Se...

    Soarkey 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<