在HashMap的實現(xiàn)原理中,詳細(xì)地介紹了HashMap的實現(xiàn)纠亚。那么你可能會問:這跟HashSet有什么關(guān)系蝶糯?
HashSet簡述
HashSet中不允許有重復(fù)元素,這是因為HashSet是基于HashMap實現(xiàn)的样眠,HashSet中的元素都存放在HashMap的key上面,而value中的值都是統(tǒng)一的一個private static final Object PRESENT = new Object();翠肘。HashSet跟HashMap一樣檐束,都是一個存放鏈表的數(shù)組。
現(xiàn)在知道了二者的關(guān)系了束倍,我們分析一下HashSet的源碼:
HashSet的構(gòu)造
對于HashSet而言被丧,它是基于HashMap實現(xiàn)的,HashSet底層使用HashMap來保存所有元素肌幽,更確切的說晚碾,HashSet中的元素,只是存放在了底層HashMap的key上喂急, 而value使用一個static final的Object對象標(biāo)識格嘁。因此HashSet 的實現(xiàn)比較簡單,相關(guān)HashSet的操作廊移,基本上都是直接調(diào)用底層HashMap的相關(guān)方法來完成
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
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);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
... ...
}
通過源碼糕簿,很容易地看出來HashSet是由HashMap構(gòu)造而成探入。
HashSet操作
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}
HashSet的操作基本上都是由HashMap來實現(xiàn)的。
總結(jié)
HashSet底層由HashMap實現(xiàn)
HashSet的值存放于HashMap的key上
HashMap的value統(tǒng)一為PRESENT
參考
JDK API:HashSet