java (Hash)Set和(Hash)Map的關係
阿新 • • 發佈:2018-11-21
這篇未完,待續寫
總述:
放一張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