1. 程式人生 > >java (Hash)Set和(Hash)Map的關係

java (Hash)Set和(Hash)Map的關係

這篇未完,待續寫

總述:

放一張Map,Set關係圖,TreeSet使用TreeMap,HashSet使用HashMap(主要)和LinkedHashMap,LinkedHashSet繼承自HashSet,呼叫了(HashSet中呼叫的LinkedHashMap).

HashSet底層是HashMap實現的,因為Set元素不能重複和Map的key也不能重複,所以Set是使用了Map的一部分功能(key的那一部分),

這是HashSet原始碼的一部分,簡單介紹下,原始碼基於jdk11

 

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;
//定義一個HashMap型別的變數map
    private transient HashMap<E,Object> map; 
//定義常量PRESENT為一個new Object物件
    private static final Object PRESENT = new Object();
    public HashSet() {
        //無參構造方法,建立一個HashMap物件,返回
        map = new HashMap<>();
    }
    public HashSet(Collection<? extends E> c) {
    //建立一個HashMap物件
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

   //當構造方法的引數為初始容量,負載因子,還有dummy不曉得,這三個引數時,返回LinkedHashMap物件
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

...
}

HashSet的add()方法:

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

呼叫Map介面(這裡是HashMap物件)的put方法,key是咱們新增到HashSet中的元素,value是之前定義的new Object

所以新增物件的時候先計算hashCode值是否存在於hash陣列表中,如果不存在,在索引位置處建立,如果存在,呼叫equals方法比較兩個元素是否相同,相同,則不存放,不相同存放到連結串列中

...................

LinkedHashSet跟LinkedHashMap的關係:

LinkedHashSet繼承自HashSet,構造方法直接呼叫父類的有三個引數的構造方法,返回LinkedHashMap物件

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }
    public LinkedHashSet() {
        super(16, .75f, true);
    }
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

TreeSet和TreeMap的關係:

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    
    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }
    public TreeSet() {
        this(new TreeMap<>());
    }
//傳入引數為Comparator的子類或者例項
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }
    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }
...
}

TreeSet的構造方法,返回的是TreeMap物件

 

 

參考:https://www.cnblogs.com/skywang12345/p/3311252.html

        https://blog.csdn.net/riverflowrand/article/details/55520145