詳解Java集合中的HashSet
在寫HashMap的時候提到過Set是基於Map實現的,HashSet基於HashMap實現,將HashSet的資料作為HashMap的Key值儲存,所以HashSet中元素不可重複,無序,允許null元素,執行緒不安全。
原始碼分析
HashSet欄位
//基於HashMap實現 private transient HashMap map; //虛擬一個value private static final Object PRESENT = new Object();
構造方法
/** * 預設無參構造,初始化了一個空的HashMap */ public HashSet() { map = new HashMap<>(); } /** * 指定容量構造 */ public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } /** * 指定容量和負載因子 */ public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } /** * 指定容量、負載因子構造一個新的集合,非public有訪問許可權 * 只有LinkedHashSet涉及到 */ HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } /** * 指定collection集合構造 */ public HashSet(Collection c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
從這裡我們可以看出HashSet基於HashMap實現
add方法
用HashMap的put方法完成HashSet的add操作,因為HashMap的key不可重複,所以HashSet中的元素不會重複,原始碼如下
public boolean add(E e) { return map.put(e, PRESENT)==null; }
remove方法
呼叫HashMap的remove方法
public boolean remove(Object o) { return map.remove(o)==PRESENT; }
contains方法
因為HashSet的元素都作為HashMap的Key值儲存,所以查詢是否包含此key
public boolean contains(Object o) { return map.containsKey(o); }
迭代
獲取HashMap的KeySet的迭代器
public Iterator iterator() { return map.keySet().iterator(); }
clone方法
屬於淺克隆
public Object clone() { try { HashSet newSet = (HashSet) super.clone(); newSet.map = (HashMap) map.clone(); return newSet; } catch (CloneNotSupportedException e) { throw new InternalError(e); } }
總結
HashSet基於HashMap實現,與HashMap一樣無序,執行緒不安全,利用HashMap的key不可重複從而實現HashSet不含重複元素
寫在最後:歡迎留言討論,點“關注”,不迷路,加關注,持續更新!