HashSet從入門到入土

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和計算機基礎知識,保證讓你看完有所收穫,不信你打我
  • 如果看完有不同的意見或者建議,歡迎多多評論一起交流。感謝各位的支持以及厚愛。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章