java集合-HashSet源碼解析

HashSet 無序集合類

  • 實現了Set接口
  • 內部經過HashMap實現
// HashSet
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    //重要:HashMap HashSet就是經過HashMap保存數據, HashSet的值就是HashMap的key
    private transient HashMap<E,Object> map;  // 使用transient修飾不會被序列化
    
    //HashMap 爲<key, value>的鍵值對, 既然HashSet的值就是HashMap的key, 那麼HashMap的值呢,固然就是這個PRESENT,HashMap全部的value都是同一個對象
    private static final Object PRESENT = new Object();
    
    // 默認構造函數,建立一個HashMap對象
    public HashSet() {
        map = new HashMap<>();
    }

    //將一個已知的collection轉換爲HashSet
    public HashSet(Collection<? extends E> c) {
        //Collection<? extends E> c 限制了類型上限爲E,也就是c只能是E類型或E的子類,防止參數是非Set類型
        //若是沒有指定HashMap的capacity, 那麼默認的就是16
        //根據 threshold = capacity * loadFactor, 能夠計算出 capacity
        //Math.max((int) (c.size()/.75f) + 1, 16) 這個意思就是capacity若是沒超過16, 那麼就直接使用默認的16
        // 容量設置爲4/3倍
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        //將已知的collection轉換爲HashSet的方法
        //addAll方法是HashSet的父類AbstractCollection的方法,爲了便於閱讀,會將代碼粘貼在下面
        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);
    }
    
    //addAll方法是HashSet的父類AbstractCollection的方法
    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false; // 只要添加了元素就返回true
        for (E e : c)
            //此處的add方法由HashSet重寫實現
            if (add(e))
                modified = true;
        return modified;
    }
    
    //HashSet的核心方法來了, 沒錯,就這麼簡單
    public boolean add(E e) {
        //應證了上面所說的key爲HashSet的值
        return map.put(e, PRESENT)==null;
    }
    
    //剩下這些方法都是跟Map相關的了,只要熟悉了HashMap, 那就太簡單了,就不說了
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

    public void clear() {
        map.clear();
    }
    
}

補充

泛型

泛型的上限通配符<? extends T>

<? extends T>是 Upper Bound(上限) 的通配符,用來限制元素的類型的上限,好比  

List<? extends Fruit> fruits;  
表示集合中的元素類型上限爲Fruit類型,即只能是Fruit或者Fruit的子類。

泛型的下限通配符<? super T>

<? super E> 是 Lower Bound(下限) 的通配符 ,用來限制元素的類型下限,好比

List<? super Apple> apples;  
表示集合中元素類型下限爲Apple類型,即只能是Apple或Apple的父類。

參考

相關文章
相關標籤/搜索