記一次HashSet的源碼閱讀記錄

                                  討厭深夜的原因是它有太多不穩定因素。

最近一直再看有關於集合方面的代碼,給我個人的感觸,如果你是有一定的數據結構知識等去看集合的源碼,相對於理解起來的話,就會更好的名字,存儲集合元素的數據結構。當然,這也不是一遍就能徹底的理解好的啦,就有個大致的理解的。最終的還是需要長期的使用不斷的提升來加強這方面,這純屬個人的感覺。

 

先上一張HashSet的關係圖吧

從這個圖就不難看出HasetSet上面的關係。然後HashSet實現起來都是基於HashMap的,利用HashMap的Key的唯一性和不重複來確保的,所以這就是我們經常和麪試官聊的HashSet是元素不重複,沒有順序的原因,因爲HashMap的Key保存也是無序的.

 

1 : 參數介紹

// 保存數據的HashMap
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map 翻譯過來的意思就是 : 與備份映射中的對象關聯的虛擬值
private static final Object PRESENT = new Object();

transient這個修飾符號,初次見到的時候也是搞不懂明白,後來百度就大致瞭解了作用,大致就是保證序列化的時候,被該字段修飾的,就不會被序列化,具體還是需要寫代碼去詳細的體驗看下效果是什麼樣子的。

 

2 : 構造函數

// 無慘構造函數;也就是初始化之前map
public HashSet() {
    map = new HashMap<>();
}
// 初始化一個map,然後調用addAll()方法來將數據都保存到map中
public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}
// 根據傳入進來的數值大小,初始化一個Map
public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
}
// 同上
public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}
// 根據傳入進來的參數,初始化一個LinkedHashMap類型的Map
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

 

  3 : 方法介紹

      從下面的這些方法中可以看出,這些核心的方法,都是繼續調用那個全局的Map的方法來實現的。

  // 長度 

public int size() {
    return map.size();
}
// 根據長度來判斷是否爲空的
public boolean isEmpty() {
    return map.isEmpty();
}
// 判斷是否包含某個元素
public boolean contains(Object o) {
    return map.containsKey(o);
}
// 進行添加,Key 是傳入進來的元素e , value 就是全局定義的Object對象
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();
}
// 克隆某個元素
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);
    }
}
// 調用迭代器,也就是調用HashMap中的方法
public Iterator<E> iterator() {
    return map.keySet().iterator();
}

 

 好啦,HashSet的源碼就是利用HashMap來實現的,當有面試官在問的時候,就說HashSet的唯一性是利用HashMap的Key來進行保證的。其實HashSet也就是利用HashMap來實現的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章