public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
//HashMap ? 沒(méi)錯(cuò)翻默,HashSet就是通過(guò)HashMap保存數(shù)據(jù), HashSet的值就是HashMap的key
private transient HashMap<E,Object> map;
//HashMap 為<key, value>的鍵值對(duì)玻褪, 既然HashSet的值就是HashMap的key, 那么HashMap的值呢玖绿,當(dāng)然就是這個(gè)PRESENT啦
private static final Object PRESENT = new Object();
//下面這一系列的構(gòu)造方法都是創(chuàng)建HashMap, 之前已經(jīng)介紹過(guò)HashMap, 這兒就不再詳說(shuō)了
public HashSet() {
map = new HashMap<>();
}
//將一個(gè)已知的collection轉(zhuǎn)換為HashSet
public HashSet(Collection<? extends E> c) {
//這兒的HashMap的參數(shù)為什么這么寫(xiě)?
//上次介紹HashMap的時(shí)候可知,如果沒(méi)有指定HashMap的capacity, 那么默認(rèn)的就是16
//根據(jù) threshold = capacity * loadFactor, 可以計(jì)算出 capacity
//Math.max((int) (c.size()/.75f) + 1, 16) 這個(gè)意思就是capacity如果沒(méi)超過(guò)16, 那么就直接使用默認(rèn)的16
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
//將已知的collection轉(zhuǎn)換為HashSet的方法
//addAll方法是HashSet的父類AbstractCollection的方法茧痕,為了便于閱讀,會(huì)將代碼粘貼在下面
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;
for (E e : c)
//此處的add方法由HashSet重寫(xiě)實(shí)現(xiàn)
if (add(e))
modified = true;
return modified;
}
//HashSet的核心方法來(lái)了恼除, 沒(méi)錯(cuò)踪旷,就這么簡(jiǎn)單
public boolean add(E e) {
//應(yīng)證了上面所說(shuō)的key為HashSet的值
return map.put(e, PRESENT)==null;
}
//剩下這些方法都是跟Map相關(guān)的了,只要熟悉了HashMap, 那就太簡(jiǎn)單了豁辉,就不說(shuō)了
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}
}
HashSet的源碼如此簡(jiǎn)單令野。下面還是對(duì)HashSet的源碼作一個(gè)總結(jié)吧:
HashSet基于HashMap實(shí)現(xiàn), 以HashSet的值作為HashMap的一個(gè)key, 以一個(gè)Object對(duì)象常量作為HashMap的值徽级。
根據(jù)HashMap的特性气破,可以推敲出:HashSet允許擁有1個(gè)為null的值, HashSet的值不可重復(fù)餐抢。
在創(chuàng)建HashSet的時(shí)候现使,如果合適,最好指定其內(nèi)部HashMap的 capacity和loadFactory的值弹澎, 至于原因朴下,在介紹HashMap的時(shí)候,提到過(guò)苦蒿。