LinkedHashSet概述
我们知道HashSet是无序的,那么LinkedHashSet从名称上我们就可以感觉到他和链表有关系,那么它是否是有序的呢?事实上,LinkedHashSet是具有可预知迭代顺序的Set接口的实现。此实现与HashSet的不同之处在于,它维护着一个运行于所有条目的双重链表。此链表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
还记得HashSet中有一个包访问权限的构造方法吗?它就是在LinkedHashSet应用到的。
LinkedHashSet声明与实现
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
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继承自HashSet。它所有的构造方法调用的都是HashSet中那个只有包访问权限的构造方法。所以LinkedHashSet底层使用的是LinkedHashMap。它就是依靠LinkedHashMap的特性来实现自身所有功能。后续我们会详细介绍LinkedHashMap。明白了LinkedHashMap,LinkedHashSet就是小菜一碟。
TreeSet概述
TreeSet也是一个有序Set,并且我们可以定义元素在TreeSet中的顺序。实现方式就是在构造时,传入我们预先定义好的Comparator。
TreeSet定义
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
我们可以看到TreeSet实现了NavigableSet接口。Navigable是可驾驭的意思。实际上就是刚刚我说的可以指定TreeSet中元素排序。
TreeSet构造
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
public TreeSet() {
this(new TreeMap<E,Object>());
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
}
public TreeSet(SortedSet<E> s) {
this(s.comparator());
addAll(s);
}
我们可以看到默认的TreeSet构造方法实际上底层使用的是TreeMap进行存储。它就是依靠TreeMap的特性来实现自身功能。
TreeSet基本属性
private transient NavigableMap<E,Object> m;
private static final Object PRESENT = new Object();
看下上面的属性,是否有点眼熟?在哪里见过。对就是在HashSet中。只不过当时的HashMap这里改成了NavigableMap。我们把TreeMap继承体系图拿出来看下:
实际上TreeMap就是实现了NavigableMap接口,所以它具有NavigableMap的特性。所以想要彻底了解TreeSet,就需要研究TreeMap,有关TreeMap的内容我们后续会讲到。