Set 集合
和List一樣,繼承Collection接口,不同的是Set中不能包含重複的元素,無序,並且最多隻能允許一個null值。Set常見的實現類有:HashSet、TreeSet和LinkedHashSet。
1.HashSet
HashSet是一個沒有重複元素的集合。它是由HashMap實現的,不能保證元素的順序,重要的是HashSet允許使用null元素。
HashSet是非同步的。如果多個線程同時訪問一個hashset,而其中至少一個線程修改了該hashset,那麼它必須保持外部同步。
Set s = Collections.synchronizedSet(new HashSet(...));
構造方法:
1)無參構造方法
通過hashset的構造函數可以看出創建hashset實際上就是創建一個hashmap。但是無參構造方法創建的hashset將會是一個容量爲16,裝載因子爲0.75的hashmap。
public HashSet() {
map = new HashMap<>();
}
2)有參構造方法
通過有參的構造方法可以指定內部hashmap的容量和裝載因子
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
3)構造方法的參數是一個集合
如果參數是一個集合,那麼hashset會把傳入集合的大小除以0.75再加上1與16進行比較,取較大的那個值作爲hashmap的容量。
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
具體的源碼分析 https://blog.csdn.net/guoweimelon/article/details/50804799
hashset對存入的元素有一些要求,爲了保證存入元素的唯一性,存儲在hashset中的元素必須重寫hashcode()和equals()方法,重寫hashcode方法是爲了根據元素自身的特性確定元素的hash值,進而確定元素在hashset中的位置,而重寫equals方法是爲了解決哈希衝突,當兩個元素通過hashcode計算出的hash值相同的時候就發生了hash衝突,這個時候,根據元素的equals方法來判斷兩個元素是否相同,如果兩個元素的內容相同,那麼重複的元素便不會存儲;如果內容不同,就會通過一個單向鏈表來存儲發送hash衝突的元素,在Java8中,若谷衝突的次數超過來8次,就會將單向鏈表轉化爲紅黑樹,從而將最壞的情況下的性能從O(n)提高到O(logn)。
2.TreeSet
是一個有序的集合,是一個set集合。繼承abstractset,實現了navigableset,cloneable,serializable接口。
源碼分析
3.LinkedHashSet