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,
後面和研究HashMap和LinkedHashMap啦,哈哈!