Java集合(一) —— Collection源碼分析
Java集合(二) —— ArrayList源碼分析
Java集合(三) —— LinkedList源碼分析
Java集合(四) —— PriorityQueue源碼分析
Java集合(五) —— HashSet源碼分析
Java集合(六) —— LinkedHashSet源碼分析
Java集合(七) —— TreeSet源碼分析
Java集合(八) —— HashMap源碼分析
Java集合(九) —— LinkedHashMap源碼分析
Java集合(十) —— TreeMap源碼分析
0.總結(稍微改變一下把敢,先來個總體概括)
1.HashSet內部是使用HashMap來存儲數據的雀监,具體來說是使用HashMap中的key存儲數據的(這就是HashSet不能存儲重復的元素的原因)罐盔,而HashMap中所有的值存儲的都將是PRESENT對象(PRESENT對象是在類加載時就已經初始化好了悼粮,并且不允許改變的)兢仰。
2.HashSet對外提供的方法噪馏,最終都是通過HashMap操作完成的痊末。
3.HashSet不能保存重復的元素(前面已經說過了)绪钥。
4.HashSet不保證插入的順序(通過hash()函數將對象映射到散列表(實際就是數組)中,所以數據在數組中不是連續(xù)存儲的)云芦。
5.HashSet的默認容量是16(事實上是HashMap的默認容量)俯逾,負載因子為0.75,也就是說默認當元素數量達到16*0.75=12之后就會發(fā)生擴容舅逸。
1.HashSet繼承關系圖
2.數據結構
// HashSet使用的是HashMap存儲數據桌肴,至于HashMap的數據結構,會在HashMap一章中詳解
private transient HashMap<E,Object> map;
3.源碼分析
3.1成員變量
// HashSet用于保存數據的HashMap
private transient HashMap<E,Object> map;
// PRESENT是map默認存儲的value琉历,基本上沒什么用坠七,我們應該也不會用到
private static final Object PRESENT = new Object();
3.2構造方法
/**
* 默認構造方法
*/
public HashSet() {
// 使用map存儲數據
map = new HashMap<>();
}
/**
* 使用指定集合構建HashSet
*/
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);
}
3.3常用方法
1.新增元素add
public boolean add(E e) {
// 實際上調用了map的put()方法保存數據;這里不再展開HashMap的源碼
return map.put(e, PRESENT)==null;
}
圖解HashSet(HashMap)存儲數據的過程
2.刪除元素
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
4.Tips
其實HashSet并沒有什么好說的,因為處理數據時灼捂,其內部基本都是調用HashMap的方法离例。我們只需要知道HashSet不能保存重復元素,不保證元素順序等特性就夠了(其實這些還是HashMap的特性)悉稠。