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