HashSet從入門到入土
Hashset是什麼
下面就是HashSet的繼承關係圖
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bMUfHjgu-1593755190238)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200702171047.png)]
HashSet內部使用的是HashMap
當我們去看HashSet的構造方法的時候我們會發現直接new了一個HashMap,並且賦給了map屬性。
即HashSet就是在HashMap上面套了個殼,方法也比較簡單,每個方法其實都是對應的操作map。
HashSet如何去重的
因爲HashSet是繼承了Set,所以就不能有重複項。我們大多數情況下使用HashSet也是因爲它有去重的功能。
要實現去重,HashSet從add方法就開始了
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
從這裏我們可以看出,HashSet的add方法調用了HashMap的put方法,但是put進去的是一個鍵值對,而HashSet存的不是鍵值對,是一個泛型。
所以說HashSet把你要存放的值當做key,而對應的value是一個final的Object對象,只起到一個佔位作用。這個時候由於HashMap不允許key重複所以正好被HashSet拿來使用用來保證其不重複。
非線程安全的
由於HashMap不是線程安全的,所以HashSet也不是線程安全的,所以在多線程,高併發的情況下慎用。
而且HashSet沒有像Hashmap那樣的多線程版本,如果想用多線程模式就使用如下的:
Set<String> set = Collections.synchronizedSet(new HashSet<String>());
或者使用ConcurrentHashMap的一個實現了Set接口的靜態內部類。
LinkedHashSet
類似的LinkedHashSet也是一個套殼的LinkedHashMap,對比HashSet它的特點就是保證數據有序,插入的時候是什麼順序,遍歷的時候就是什麼順序
無參構造函數
public LinkedHashSet() {
super(16, .75f, true);
}
由於LinkHashSet繼承自HashSet所以其實是調用了HashSet的三個參數的構造函數
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
這次不是new一個HashMap了而是new了一個LinkedHashMap,這就是它能保證有序的關鍵,LinkedHashMap用雙向連敗OA的方式在HashMap的基礎上額外保存了鍵值對的插入順序
由於LinkedHashMap可以保證鍵值對的順序所以用來實現簡單的LRU緩存。
所以當你既要保證元素無重複,又要保證元素有序,可以使用LinkedHashSet
最後
- 如果覺得看完有收穫,希望能給我點個贊,這將會是我更新的最大動力,感謝各位的支持
- 歡迎各位關注我的公衆號【java冢狐】,專注於java和計算機基礎知識,保證讓你看完有所收穫,不信你打我
- 如果看完有不同的意見或者建議,歡迎多多評論一起交流。感謝各位的支持以及厚愛。