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
接口的官方文档并未给出答案,所以需要接口实现类来决定。以 TreeSet
和 TreeMap
类为例,它们都优先采用 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
的基础上新增了如下几个方法:
public interface SortedSet<E> extends Set<E> {
Comparator<? super E> comparator();
// 左闭右开
SortedSet<E> subSet(E fromElement, E toElement);
SortedSet<E> headSet(E toElement);
SortedSet<E> tailSet(E fromElement);
E first();
E last();
default Spliterator<E> spliterator() {...}
}
遍历顺序
SortedSet
接口官方文档规定:sorted set 的迭代器采用升序遍历(The set’s iterator will traverse the set in ascending element order)。