public class TreeSet
extends AbstractSet
implements NavigableSet, java.io.Serializable
public interface NavigableSet
extends SortedSet TreeSet实现了SortedSet接口,顾名思义这是一种排序的Set集合
TreeSet是SortedSet接口的唯一实现类。TreeSet没有自己的数据结构而是通过TreeMap实现的,所以TreeSet也是基于红黑二叉树的一种存储结构,所以TreeSet不允许null对象,并且是有序存储的(默认升序)。
相对HashSet来说,TreeSet提供了一些额外的按排序位置访问元素的方法,例如first(), last(), lower(), higher(), subSet(), headSet(), tailSet()
private transient NavigableMap
m; private static final Object PRESENT = new Object();
NavigableMap是继承自SrotedMap的一个接口,其实现类为TreeMap,因此TreeSet中的数据是通过TreeMap来存储的
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}public boolean remove(Object o) {
return m.remove(o)==PRESENT;
}使用PRESENT的理论是,使用一个对象,remove和add,key存在时操作返回true,key不存在时返回false,可以对key是否存在作出区分。当PRESENT为null时,是无法区分的。
TreeSet() 空的构造器,初始化一个空的TreeMap,默认升序排列
TreeSet(Comparator super E> comparator) 传入一个自定义的比较器,常常用于实现降序排列
TreeSet(Collection extends E> c) 传入一个子集c,用于初始化TreeMap对象,默认升序
TreeSet(SortedSets) 传入一个有序的子集s,用于初始化TreeMap对象,采用子集的比较器
public TreeSet() {
this(new TreeMap<>());
}public TreeSet(Comparator super E> comparator) {
this(new TreeMap<>(comparator));
}public TreeSet(Collection extends E> c) {
this();
addAll(c);
}public TreeSet(SortedSet
s) {
this(s.comparator());
addAll(s);
}
TreeSet的排序分两种类型,一种是自然排序,另一种是定制排序。
TreeSet 会调用compareTo方法比较元素大小,然后按升序排序(从小到达)。所以自然排序中的元素对象,都必须实现了Comparable接口,否则会跑出异常。对于TreeSet判断元素是否重复的标准,也是调用元素从Comparable接口继承而来compareTo方法,如果返回0则是重复元素。Java的常见类都已经实现了Comparable接口给Person类上添加针对Comparable接口的实现:考虑具体的业务规则,按照类中什么属性进行排序比较
TreeSet还有一种排序就是定制排序,定制排序时候,需要关联一个 Comparator对象,由Comparator提供排序逻辑
构造器
public TreeSet(Comparator super E> comparator) {
this(new TreeMap<>(comparator));
}Set
set=new TreeSet<>((obj1, obj2)->{
Person p1=(Person)obj1;
Person p2=(Person)obj2;
return p2.getId().compareTo(p1.getId());
});
for(int i=0;i<10;i++)
set.add(new Person(1L+i, (9-i)+"name"));
set.forEach(System.out::println);
Java中为了实现对象的比较引入了compare算法
这里用于实现了两个日期的比较大小,如果返回为0则表示两个对象相等,如果返回为1则表示d1大于参数;如果返回-1表示d1小于参数实现Comparable接口,在类定义中添加比较规则
public class Person implements Comparable{
private Long id;
private String name;
public int compareTo(Person person){
if(name!=null && name.trim().length()>0)
return this.name.compareTo(person.name);
return 0;
}
}
Setset=new TreeSet<>();
for(int i=0;i<10;i++)
set.add(new Person(1L+i, (9-i)+"name"));
set.forEach(System.out::println);