Java基础之Collections框架Set实现类LinkedHashSet及其源码分析
LinkedHashSet的简单使用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啦,哈哈!