Java集合之HashSet源碼剖析(jdk1.8)
1、簡介
HashSet是Set接口下常用的實現類。
HashSet的實現主要使用HashMap的key來滿足Set的特性:不重複,並且也是無序的。
HashSet的繼承圖譜如下:
實現的都是些基礎接口。
2、源碼解析
HashSet的源碼內容不多,主要部分都是調用HashMap實現得。
1、屬性
主要屬性就兩個:
//底層是HashMap,只使用key
private transient HashMap<E,Object> map;
//用於充當map的value,畢竟map是需要有value的
private static final Object PRESENT = new Object();
2、構造方法
五個構造方法,可以看到都是調用的HashMap構造函數,最後那個調用的是LinkedHashMap的構造方法。
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);
}
//這個構造方法是給LinkedHashSet使用的
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
3、重要方法
因爲是調用的HashMap來實現的,所以主要方法基本都和HashMap相關。
//迭代器
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
//Set沒有索引,所以直接判斷是否在容器中
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();
}
}
沒了。。。。真的沒了。
3、總結
(1)HashSet底層基於HashMap,HashMap的key是不重複的且無序。
(2)阿里手冊上有說,使用java中的集合時要自己指定集合的大小,假如,我們預估HashMap要存儲n個元素,那麼,它的容量就應該指定爲((n/0.75f) + 1),如果這個值小於16,那就直接使用16得了。
初始化時指定容量是爲了減少擴容的次數,提高效率。
(3)HashSet線程不安全。
(4)HashSet中允許有一個null,因爲HashMap中的key允許有一個null.