LinkedHashSet对于HashSet就如LinkedHashMap对于HashMap一样,因此也很容易理解。
首先,继续看一看它所处的体系结构:
由于HashSet是无序的,因此LinkedHashSet主要的特点是让自己的元素保持一定的顺序。
继续看它的继承体系:
LinkedHashSet继承自HashSet,并实现了HashSet一样的接口,至于这些接口的方法也就不赘述了。
class LinkedHashSet<E> extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable{
再继续看看它的成员变量:
private static final long serialVersionUID = -2851667679971038690L;
//序列化标志,用于反序列化
发现它自己根本就没有任何成员变量,都是通过HashSet继承而来的。
继续看其构造器:
public LinkedHashSet(int initialCapacity, float loadFactor){
//构造器1,参数为默认容量与加载因子,调用父类构造器
super(initialCapacity, loadFactor, true);
//此处的true是为了找到准确的父类构造器,即能够创建LinkedHashMap类的构造器
}
public LinkedHashSet(int initialCapacity){
//构造器2,参数为默认容量,默认加载因子为0.75
super(initialCapacity,.75f,true);
}
public LinkedHashSet(){
//构造器3,空参,默认容量为16,默认加载因子为0.75
super(16,.75f,true);
}
public LinkedHashSet(Collection<? extends E> c){
//构造器4,传入一个集合c
super(Math.max(2 * c.size(),11),.75f,true);
//这里的capacity为什么要这样设置????
addAll(c);
}
HashSet(initialCapacity, float loadFactor, boolean dummy){
//构造器5,非公开的,用于创造一个有序的HashMap,此处是为LinkedHashSet留后路
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
LinkedHashSet有四个构造器,当参数为初始容量与加载因子时,直接调用父类的构造器,由于上一篇讲过了,其父类HashSet构造器有五个,而其最后一个构造器的参数是初始容量、加载因子与一个无用的dummy。而这个dummy则是用于LinkedHashSet的构造器调用的识别器。进入父类构造器后再创建LinkedHashMap类并将其赋给map。当参数为初始容量时,则将加载因子设置为0.75再调用父类的构造器;当为空参时,则设置初始容量为16,默认加载因子为0.75再调用父类构造器;当参数为集合c时,首先根据c的大小获得合适的初始容量(此处有些不解,为什么要取c大小的两倍和11的最大值作为初始容量,这种取值方法只在Hashtable中见过,笔误?但是这个传进去最后在HashMap中还是要转化成16或者2的整数次幂,也不影响其构造,但是查阅网络资料也没有获得一个比较好的解释,疑问暂留)再将加载因子设置为0.75并调用父类构造器。
除了构造器之外,LinkedHashSet没有其他的常用方法了,都是从HashSet中继承来到方法,并且可以直接使用,HashSet和LinkedHashSet两者唯一的区别就是LinkedHashSet比HashSet多了一个可以分别结点插入顺序或访问顺序的链表。
常用方法:
1.add
2.remove
3.contains
4.size
5.clear
6.isEmpty
总源码
public class LinkedHashSet<E> extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable{
//LinkedHashSet继承于HashSet,建立于LinkeHashMap之上,其余的都和HashSet差不多
private static final long serialVersionUID = -2851667679971038690L;
//序列化标志,用于反序列化
public LinkedHashSet(int initialCapacity, float loadFactor){
//构造器1,参数为默认容量与加载因子,调用父类构造器
super(initialCapacity, loadFactor, true);
//此处的true是为了找到准确的父类构造器,即能够创建LinkedHashMap类的构造器
}
public LinkedHashSet(int initialCapacity){
//构造器2,参数为默认容量,默认加载因子为0.75
super(initialCapacity,.75f,true);
}
public LinkedHashSet(){
//构造器3,空参,默认容量为16,默认加载因子为0.75
super(16,.75f,true);
}
public LinkedHashSet(Collection<? extends E> c){
//构造器4,传入一个集合c
super(Math.max(2 * c.size(),11),.75f,true);
//这里的capacity为什么要这样设置????
addAll(c);
}
@Override
public Spliterator<E> spliterator(){
//获取分割器
return Spliterators.spliterator(this,Spliterator.DISTINCT | Spliterator.ORDERED);
}
}
参考资料: