HashSet 和 LinkedHashSet 的关系类似于 HashMap 和 LinkedHashMap 的关系,即后者维护双向链表,实现迭代顺序可为插入顺序或是访问顺序。所以也就轻松加愉快快速了解一下即可。

从源码中可以看到其空的构造函数为:

1
2
3
public LinkedHashSet() {
super(16, .75f, true);
}

这个super即父类是HashSet,从它的继承关系就可以显然看到:

1
2
3
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable

那么HashSet内部的数据结构就是一个 HashMap,其方法的内部几乎就是在调用 HashMap 的方法。

LinkedHashSet 首先我们需要知道的是它是一个 Set 的实现,所以它其中存的肯定不是键值对,而是值。此实现与 HashSet 的不同之处在于,LinkedHashSet 维护着一个运行于所有条目的双向循环链表。

这一切都与LinkedHashMap类似。

LinkedHashSet 内部有个属性 accessOrder 控制着遍历次序。默认情况下该值为 false ,即按插入排序访问。如果将该值设置为 true 的话,则按访问次序排序(即最近最少使用算法,最近最少使用的放在链表头部,最近访问的则在链表尾部)。

一、 示例

HashSet的遍历:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
Set<String> linkedHashSet = new HashSet<>();
linkedHashSet.add("aaa");
linkedHashSet.add("eee");
linkedHashSet.add("ccc");
linkedHashSet.add("bbb");

Iterator<String> it = linkedHashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}

输出结果是:

aaa
ccc
bbb
eee

LinkedHashSet的遍历:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("aaa");
linkedHashSet.add("eee");
linkedHashSet.add("ccc");
linkedHashSet.add("bbb");
linkedHashSet.add(null);

Iterator<String> it = linkedHashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}

}

输出结果是:

aaa
eee
ccc
bbb
null

可以看到与输入顺序是一致的。