TreeSet的实现原理基于TreeMap,请阅读该博文前,先学习TreeMap的实现原理。
类结构
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
成员变量
private transient NavigableMap<E,Object> m;//在构造方法中,会被替换成功TreeMap,采用了适配器设计模式。
private static final Object PRESENT = new Object();//和HashSet一样,该属性只是替代所有HashMap.put(key,value)中的value
构造方法
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(NavigableMap<E,Object> m) {
this.m = m;
}
且传入的都是TreeMap。
增删改查...
//添加元素
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
//清除元素
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
//清除集合
public void clear() {
m.clear();
}
....等一系列对外公开的方法
可以发现,TreeSet的所有对外公开发方法全部是通过TreeMap去实现的。
所以TreeSet同样拥有TreeMap拥有的特点。
也分为自然排序和比较器排序
自然排序
@Test
public void naturalTest(){
Set set = new TreeSet();
set.add("a");
set.add("aaaa");
set.add("aa");
set.add("aaaaa");
set.add("a");
set.add("12345");
Iterator itr = set.iterator();
while(itr.hasNext()){
System.out.println(itr.next().toString());
}
}
输出结果:
12345
a
aa
aaaa
aaaaa
自定义比较器排序
public void compareTest(){
class DemoComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
if(o1.length()==o2.length() && o1.equals(o2)){
return 0;
}else if(o1.length()<o2.length()){
return 1;
}else{
return -1;
}
}
}
Set set = new TreeSet(new DemoComparator());
set.add("a");
set.add("aaaa");
set.add("aa");
set.add("aaaaa");
set.add("a");
set.add("12345");
Iterator itr = set.iterator();
while(itr.hasNext()){
System.out.println(itr.next().toString());
}
}
输出结果:
12345
aaaaa
aaaa
aa
a