Java基礎之Collections框架Set實現類LinkedHashSet及其源碼分析

Java基礎之Collections框架Set實現類LinkedHashSet及其源碼分析


Set接口的哈希表和鏈表實現,具有可預測的迭代順序。 此實現與HashSet的不同之處在於,它維護在其所有條目中運行的雙向鏈接列表。 此鏈表定義了迭代順序,即將元素插入集合中的順序(插入順序)。請注意,如果將元素重新插入到集合中,則插入順序不會受到影響。 (如果在調用之前s.contains(e)將返回true的情況下調用s.add(e),則將元素e重新插入到set s中。)
此實現使客戶免於HashSet提供的未指定的,通常混亂的排序,而不會導致與TreeSet相關的增加的成本。 無論原始集的實現如何,都可以使用它來產生與原始集順序相同的集合副本。
LinkedHashSet類提供所有可選的Set操作,並允許空元素。 像HashSet一樣,它爲基本操作(添加,包含和刪除)提供恆定時間的性能,假設哈希函數將元素正確地分佈在存儲桶中。 由於維護鏈接列表會增加開銷,因此性能可能會略低於HashSet,但有一個例外:在LinkedHashSet上進行迭代需要的時間與集合的大小成正比,而無論其容量如何。 在HashSet上進行迭代可能會更昂貴,需要的時間與其容量成正比。
鏈接的哈希集具有兩個影響其性能的參數:初始容量和負載因子。LinkedHashSet類的迭代時間不受容量的影響。

LinkedHashSet的簡單使用

LinkedHashSet擁有Set集合的所有的功能,簡單列舉了幾個:

	//創建一個LinkedHashSet
	Set<String> setLinked = new LinkedHashSet<String>();
	//添加元素
   setLinked.add("tony");
   setLinked.add("supers");
   System.out.println(setLinked.toString());
	//移除元素
    setLinked.remove("tony");
    System.out.println(setLinked.toString());
    //添加元素
    setLinked.add("tony");
    System.out.println(setLinked.toString());
    //檢查是否包含元素
    boolean boo = setLinked.contains("tony");
    System.out.println(boo);
    //添加元素
    setLinked.add("tony");
    System.out.println(setLinked.toString());
    
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("tony");
    //添加指定列表中的元素,添加的元素如果存在將不會將會重新插入,並不影響排序
    setLinked.addAll(list);
    System.out.println(setLinked.toString());
    //移除指定元素
    setLinked.remove("a");
    System.out.println(setLinked.toString());
    ......

LinkedHashSet源碼分析

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {
	//序列號
    private static final long serialVersionUID = -2851667679971038690L;

    /**
     構建一個LinkedHashSet指定初始容量和負載因子
     */
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    /**
     構建一個LinkedHashSet指定初始容量和默認的負載因子
     */
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    /**
    構建一個LinkedHashSet默認的容量和默認的負載因子
     */
    public LinkedHashSet() {
        super(16, .75f, true);
    }

    /**
    構建一個LinkedHashSet默認的容量和默認的負載因子,並將指定的集合元素添加到LinkedHashSet中
     */
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

    /**
    返回spliterator實例
     */
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}

通過源碼可以看出,創建的時候(即構造函數)是使用super中的方法,有繼承關係可以看出繼承關係,可以看出是調用HashSet類中的相關方法。

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

通過上面的代碼可以看出其實是操作LinkedHashMap的相關實例進行操作的。如果是HashSet的話將會構建一個HashMap,
後面和研究HashMapLinkedHashMap啦,哈哈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章