SortedSet 接口

SortedSet 接口继承自 Set 接口,它在 set 的基础上增加了有序性。所以对于 sorted set,最重要的是明白element 的排序机制。官方文档的描述为:

The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time.

即 sorted set 的排序机制有两种:要么所有的 element 都实现 Comparable 接口(即 natural ordering);要么在创建 sorted set 时,提供一个 Comparator 接口实现类。

Comparable 与 Comparator

Comparable 接口声明了一个 int compareTo(T o) 方法;而 Comparator 接口则声明了一个 int compare(T o1, T o2) 方法,关于这两个方法的总结如下表所示:

a.compareTo(b) 返回值 compare(a, b) 返回值
a > b 正整数 正整数
a = b 0 0
a < b 负整数 负整数
  • 其中 a、b 都不为 null

此外,你需要特别注意 compareTo()compare() 在处理 null 时,官方文档有不一样的规定:

  • compareTo() 禁止传入 null ,一旦传入,则抛出 NullPointerException 异常;
  • compare() 未规定一定不能传入 null ,但如果传入后抛出 NullPointerException 异常,则表示此 comparator 禁止参数为 null

那 sorted set 的 element 可以为 null?如果使用 natural ordering,则不能为 null ,但如果使用 comparator 排序,则可以为 null 。当然这仅仅是从理论层面进行讨论,以 TreeSet 类为例,它就不允许element 为 null

而这又引出了另一个问题:如果 element 既实现了 Comparable 接口,又在创建 sorted set 时提供了 comparator,且该 comparator 允许 element 为 null那 sorted set 该选择哪种排序机制呢

SortedSet 接口的官方文档并未给出答案,所以需要接口实现类来决定。以 TreeSetTreeMap 类为例,它们都优先采用 comparator 排序,如果未提供 comparator,则采用 natural ordering。

consistent with equals

set 的唯一性是基于 equals() 方法判断的,而 sorted set 的有序性是基于 compareTo()compare() 方法进行比较的,且 sorted set 继承自 set,所以 compareTo()compare() 的结果应与 equals() 的结果保持一致:

即当 e1.equals(e1) 的返回值为 true 时, e1.compareTo(e2)compare(e1, e2) 的返回值应也为 true ,反之亦然(e1 和 e2 都不为 null )。

新增的方法

SortedSet 接口在 Set 的基础上新增了如下几个方法:

  1. public interface SortedSet<E> extends Set<E> {
  2. Comparator<? super E> comparator();
  3. // 左闭右开
  4. SortedSet<E> subSet(E fromElement, E toElement);
  5. SortedSet<E> headSet(E toElement);
  6. SortedSet<E> tailSet(E fromElement);
  7. E first();
  8. E last();
  9. default Spliterator<E> spliterator() {...}
  10. }

遍历顺序

SortedSet 接口官方文档规定:sorted set 的迭代器采用升序遍历(The set’s iterator will traverse the set in ascending element order)。