TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。
TreeSet底层使用红黑树结构存储数据
TreeSet 两种排序方法:自然排序 和 定制排序。默认情况下,TreeSet 采用自然排序。
TreeSet和后面要讲的TreeMap采用红黑树的存储结构。
特点:有序,查询速度比链表快。
排序:
自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列
如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
实现 Comparable 的类必须重写 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小, 正数this大于参数, 0两个对象相等, 负数参数大于this。
Comparable 的典型实现:
BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
Character:按字符的 unicode 值来进行比较
Boolean:true 对应的包装类实例大于 false 对应的包装类实例
String:按字符串中字符的 unicode 值进行比较
Integer: 比较数字的大小
Date、Time:后边的时间、日期比前面的时间、日期大
TreeSet的自然排序要求元素所属的类实现Comparable接口;我们想要往TreeSet里添加一些自定义的类,compareTo方法的逻辑就必须要我们自己编写,就是定制排序。
要实现定制排序,需要将实现Comparable接口,重写compareTo方法。
此时,仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。
向 TreeSet 中添加元素时,只有第一个元素自己和自己比较,后面添加的所有元素都会调用compareTo()方法进行比较。
使用定制排序判断两个元素相等的标准是:通过compareTo方法是否返回0。
当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与 compareTo(Object obj) 方法有一致的结果;
如果两个对象通过 equals() 方法比较返回 true,则通过 compareTo(Object obj) 方法比较应返回 0。 否则,就违背了Set的定义。
定制排序也可以使用构造方法设置排序规则,设置好规则后,add的元素无需实现Comparable接口 public TreeMap(Comparator<? super K> comparator)
利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。