上一篇我们分析了LinkedHashMap的源码,发现其底层实现原理就是HashMap加一个双向链表来维持数据的插入顺序或者访问顺序,并且我们也谈到了,其底层的双向链表设计的十分巧妙,与hash表共用了key,value。像HashMap与HashSet的关系一样,与LinkedHashMap对应的是LinkedHashSet,它是一个集合,也可以维持插入顺序,但是不能维持访问顺序!
下面我们直接看源码:
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
private static final long serialVersionUID = -2851667679971038690L;
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
public LinkedHashSet() {
super(16, .75f, true);
}
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
}
额......是的!!这就是LinkedHashSet的所有源码了。我们发现LinkedHashSet继承自HashSet,实现了Set接口。提供了四个构造函数,均是调用父类HashSet的HashSet(int initialCapacity, float loadFactor, boolean dummy)这一构造函数,我们来看看父类的构造函数怎么写的:
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
在父类HashSet中,这一构造函数的访问权限并不是public的,它的访问权限只是包可见的。在分析HashSet的源码时,我们已经知道了HashSet的实现就是其内部握有一个HashMap的引用,利用HashMap中key不能重复来实现集合中没有重复的元素。这里LinkedHashSet的内部握有的是LinkedHashMap的引用,所以它也可以维持集合内的插入顺序。由于LinkedHashSet不能调用LinkedHashMap下面这个构造函数:
public LinkedHashMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
所以LinkedHashSet不能维持访问顺序!