HashSet源碼閱讀

HashSet的實現基於HashMap函數

看幾個簡單的初始化方法spa

    public HashSet() {
        map = new HashMap<>();
    }
    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);
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

能夠看到HashSet的全部初始化,其實都在初始化hashmap,能夠看出HashSet和HashMap是has-a的形式。最後一個初始化的是使用LinkedHashMap,dummy參數只是爲了作區分構造函數,能夠忽略。code

看一個HashSet的add操做blog

    private static final Object PRESENT = new Object();
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

能夠看出,add時,將添加的元素做爲hashmap的鍵值,PERSENT做爲默認的值,put到map中。繼承

例如contains、remove等相似的處理,將值做爲map的key值在map中操做。ci

不過HashSet繼承了AbstractSet,AbstractSet繼承了AbstractCollection。rem

例如剛剛的構造函數裏有個addAll方法,調用的是父類AbstractCollection中的addAll方法hash

    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

而add(e)在HashSet又獲得了重寫。it

再看看LinkedHashSet這個類,這個類的構造函數都調用父類HashSet的特殊構造方法io

    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

而HashSet這個構造方法是經過使用LinkedHashMap來實現的

相關文章
相關標籤/搜索