Set接口的实现类---TreeSet

TreeSet

类定义

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>,

    Cloneable,

    java.io.Serializable

public interface NavigableSet<E> extends SortedSet<E>

TreeSet实现了SortedSet接口,顾名思义这是一种排序的Set集合 

TreeSet是SortedSet接口的唯一实现类。TreeSet没有自己的数据结构而是通过TreeMap实现的,所以TreeSet也是基于红黑二叉树的一种存储结构,所以TreeSet不允许null对象,并且是有序存储的(默认升序)。

相对HashSet来说,TreeSet提供了一些额外的按排序位置访问元素的方法,例如first(), last(), lower(), higher(), subSet(), headSet(), tailSet()

属性 

private transient NavigableMap<E,Object> 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(SortedSet<E> s) 传入一个有序的子集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<E> s) {
        this(s.comparator());
        addAll(s);
}

TreeSet分类 

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<Person> 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<Person>{
    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;
    }
}


Set<Person> set=new TreeSet<>();
for(int i=0;i<10;i++)
    set.add(new Person(1L+i, (9-i)+"name"));
set.forEach(System.out::println);

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值