jdk源碼分析(六)——HashSet


我們?cè)?a href="http://www.lxweimin.com/p/69ac46f2a7f2" target="_blank">jdk源碼分析(四)——ArrayList和jdk源碼分析(五)——HashMap中分別分析了List和Map兩種數(shù)據(jù)結(jié)構(gòu),在Java的集合框架中,還有另一類(lèi)成員,就是Set,今天我們就來(lái)看看常用的HashSet

一.類(lèi)定義

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

可以看到,和HashMap類(lèi)似,HashSet也是繼承了一個(gè)抽象類(lèi),并實(shí)現(xiàn)了一個(gè)基礎(chǔ)的接口Set。

Set接口中的主要方法如下:

核心的方法都是一些對(duì)集合的操作,例如添加元素,判斷元素是否存在,遍歷,刪除等。

二.存儲(chǔ)結(jié)構(gòu)

HashSet主要是使用HashMap來(lái)實(shí)現(xiàn)元素的存儲(chǔ)的:

// 存儲(chǔ)集合元素
private transient HashMap<E,Object> map;
// 常量,表示某個(gè)集合元素存在,在map中作為value
private static final Object PRESENT = new Object();

因此主要操作都是圍繞著這個(gè)map進(jìn)行的,自然不可避免的要使用到我們上一篇中講到的HashMap了。mapvalueObject類(lèi)型的常量。

三.常用方法

1.構(gòu)造方法

先來(lái)看看無(wú)參構(gòu)造方法:

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

代碼很簡(jiǎn)單,只有一行,完成對(duì)map的實(shí)例化,以備使用。

除了無(wú)參構(gòu)造方法外,還可以基于已有的集合類(lèi)來(lái)初始化HashMap

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

首先調(diào)用了HashMap的構(gòu)造方法,并指定map的初始容量。初始容量的計(jì)算方法如下:
(1)將集合中的元素個(gè)數(shù)除以0.75,向上取整
(2)?。?)中結(jié)果與16中的較大者
通過(guò)HashMap的源碼分析,我們已經(jīng)知道,HashMap的默認(rèn)裝載因子是0.75(也就是說(shuō),默認(rèn)只裝載75%左右的位置),而HashSet底層使用HashMap來(lái)存儲(chǔ),因此需要根據(jù)這個(gè)裝載因子算出需要的散列表大小。而HashMap的默認(rèn)大小是16,因此這里的初始化大小最小是16。

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

邏輯實(shí)現(xiàn)也很簡(jiǎn)單,就是調(diào)用HashMapput方法,將需要存儲(chǔ)的集合元素作為key,將常量PRESENT作為value。put方法的返回值是map中與此key關(guān)聯(lián)的value值,某個(gè)元素第一次存入時(shí)返回null,如果key已經(jīng)存在,則返回此key對(duì)應(yīng)的value。

需要注意的是,HashMap是允許key覆蓋的,而集合Set的特性決定了,Set中同一個(gè)元素只能存在一次,因此,如果集合中已經(jīng)存在該元素了,那么map的返回值為非null,從而add方法返回false。

3.contains方法
public boolean contains(Object o) {
    return map.containsKey(o);
}

該方法也比較簡(jiǎn)單,直接調(diào)用HashMapcontainsKey方法來(lái)判斷元素是否存在。

HashSet的實(shí)現(xiàn)比較容易理解,我們就不再啰嗦了,輕松加愉快。期待與大家一起學(xué)習(xí)后面的jdk源碼。

本文已遷移至我的博客:http://ipenge.com/54585.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 一、基本數(shù)據(jù)類(lèi)型 注釋 單行注釋?zhuān)?/ 區(qū)域注釋?zhuān)?* */ 文檔注釋?zhuān)?** */ 數(shù)值 對(duì)于byte類(lèi)型而言...
    龍貓小爺閱讀 4,288評(píng)論 0 16
  • 實(shí)際上,HashSet 和 HashMap 之間有很多相似之處,對(duì)于 HashSet 而言,系統(tǒng)采用 Hash 算...
    曹振華閱讀 2,525評(píng)論 1 37
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,518評(píng)論 0 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,765評(píng)論 18 399
  • HashMap 是 Java 面試必考的知識(shí)點(diǎn),面試官?gòu)倪@個(gè)小知識(shí)點(diǎn)就可以了解我們對(duì) Java 基礎(chǔ)的掌握程度。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,705評(píng)論 9 107