java基礎:HashSet/LinkedHashSet/TreeSet — 源碼分析

其餘更多java基礎文章:
java基礎學習(目錄)java


Set集合的底層都是使用相對應的Map。HashSet底層是HashMap,LinkedHashSet底層是使用LinkedHashMap,TreeSet底層是使用TreeMap。都相對簡單,因此就放在一篇文章裏講解了。只簡單講一下HashSet的源碼,由於其餘二者大同小異。安全

HashSet

數據結構和基礎字段

private transient HashMap<E,Object> map;

    private static final Object PRESENT = new Object();
複製代碼

顯而易見,hashSet的底層和方法就是使用hashmap。Set實現值不重複的原理就是在保存值到底層hashmap裏的時候,保存爲key值,value值爲常量PRESENT。具體能夠看下面方法講解。bash

方法細節

構造方法

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);
    }
複製代碼

簡單的構造方法,就不闡述了。數據結構

add方法

//這個方法就能夠得知HashSet添加的元素是不可以重複的,緣由是什麼呢,set將每次添加的元素度是經過map中的key來保存,當有
//相同的key時,也就是添加了相同的元素,那麼map會講value給覆蓋掉,而key仍是原來的key,因此,這就是set不可以重複的緣由。這個方法的PRESENT能夠看下面的註釋,
//返回值的式子的意思很好理解,map中增長元素是先經過key查找有沒有相同的key值,若是有,則覆蓋value,返回oldValue。沒有
//,則建立一個新的entry,而且返回null值。若是key等於null,也會返回null值。因此return會有一個==null的判斷

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
複製代碼

remove方法

//set經過判斷刪除元素是否爲常量PRESENT,來肯定是否成功刪除
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

    //hashmap中的remove方法
    public V remove(Object key) {
        Entry<K,V> e = removeEntryForKey(key);
        return (e == null ? null : e.value);
    }
複製代碼

總結

  1. 元素沒有順序(如今知道爲何沒有順序了把,由於底層用的是HashMap,HashMap自己中的元素度沒有順序,那麼HashSet更不可能有了)
  2. 元素不能重複,集合元素能夠是null,但只能放入一個null(這個也很好理解了,由於HashSet中存放的元素,度是看成HashMap的key來使用,HashMap中key是不能相同的,因此HashSet的元素也不能重複了)  
  3. 非線程安全。
  4. HashSet使用成員對象來計算hashcode值,對於兩個對象來講hashcode可能相同,因此equals()方法用來判斷對象的相等性,若是兩個對象不一樣的話,那麼返回false。因此若是存儲自定義對象,須要重寫自定義對象的hashcode方法和equals方法。
  5. TreeSet能夠確保集合元素處於排序狀態。TreeSet支持兩種排序方式,天然排序 和定製排序,其中天然排序爲默認的排序方式。
  6. LinkedHashSet集合一樣是根據元素的hashCode值來決定元素的存儲位置,可是它同時使用鏈表維護元素的次序,當遍歷該集合時候,LinkedHashSet將會以元素的添加順序訪問集合的元素。LinkedHashSet建立的時候只會建立以插入順序排序的LinkedHashMap。
相關文章
相關標籤/搜索