Java8 HashSet 源碼閱讀

1. 概述

HashSet 保證元素不重複的集合,查詢元素、新增元素、刪除元素的時間複雜度均爲 O(1)。

HashSet 底層的數據結構爲 HashMap,map 中存儲的鍵值對,key 爲 Set 集合中的元素,value 使用同一個靜態常量(即下面代碼中的PRESENT);

private transient HashMap<E,Object> map;

private static final Object PRESENT = new Object();

HashSet 新增元素使用 HashMap 的 put 方法不斷的去替換以前的元素(保證元素不重複),HashMap 的 put 時間複雜度爲 O(1),所以 HashSet 新增元素的時間複雜度也爲 O(1); HashSet 查詢是否存在元素使用 HashMap 的 containsKey 方法,所以時間複雜度爲 O(1);HashSet 刪除元素 使用 HashMap 的 remove 方法, 時間複雜度也爲 O(1);

2. 構造函數

無參構造函數,初始化一個空的 hashMap;

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

使用集合構造一個set,容器大小爲集合大小的4/3倍和16的最大值:

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

使用初始容量和加載因子:

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

初始容量作爲唯一的構造函數:

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

default 級別的構造函數,供 LinkedHashSet 使用;

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

3. 方法

集合元素的迭代器,返回的數據是無序的:

    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

是否包含某元素,調用 HashMap 的 containsKey 方法;

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

新增元素,使用HashMap的put方法:

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

移除元素,使用HashMap的remove方法:

    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

淺拷貝:

@SuppressWarnings("unchecked")
    public Object clone() {
        try {
            HashSet<E> newSet = (HashSet<E>) super.clone();
            newSet.map = (HashMap<E, Object>) map.clone();
            return newSet;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章