1. 程式人生 > >JDK源碼分析(五)——HashSet

JDK源碼分析(五)——HashSet

http time ble 實現 addall can tor previous transient

目錄

  • HashSet概述
  • 內部字段及構造方法
  • 存儲元素
  • 刪除元素
  • 包含元素
  • 總結

HashSet概述

??從前面開始,已經分析過集合中的List和Map,今天來介紹另一種集合元素:Set。這是JDK對HashSet的介紹:

This class implements the Set interface, backed by a hash table (actually a HashMap instance). 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實現了Set接口,實際上是借助HashMap來實現的,HashSet不保證叠代時順序,也不保證存儲的元素的順序保持不變。HashSet允許插入Null。介紹了HashSet的兩個特點:無序,允許插入空值。

繼承結構

技術分享圖片

  • Set 是繼承於Collection的接口。它是一個不允許有重復元素的集合。
  • HashSet繼承AbstractSet,Abstract繼承於AbstractCollection,AbstractCollection實現了Set中的絕大部分函數,為Set的實現類提供了便利。HashSet實現Set接口借助了HashMap。

內部字段及構造方法

內部字段

    //序列化
    static final long serialVersionUID = -5024744406713321676L;

    //通過HashMap實例實現Set接口
    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    //存入HashMap中鍵值對的值
    private static final Object PRESENT = new Object();

構造方法

    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);
    }

存儲元素

??調用了HashMap的put方法插入以插入元素e為鍵,Object對象PRESENT為值的鍵值對,通過比較返回值是否為null判斷插入是否成功,因為HashMap的put方法插入的鍵值對已經存在,那麽它會返回鍵值對的值,也就是PRESENT;如果不存在就返回null。從而實現不能插入重復值。HashMap的put方法返回:the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.)

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

刪除元素

??調用HashMap的remove方法

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

包含元素

??調用HashMap的containsKey方法查找是否存在以當前元素作為key的鍵值對

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

總結

??HashSet比較簡單,它存儲元素是無序的,可以插入null,基於HashMap實現,所以它也是線程不安全的。

JDK源碼分析(五)——HashSet