Jakob Jenkov 2019-09-28
Java 的 SortedSet 接口(java.util.SortedSet)是 java.util.Set 接口的子类型。与普通 Set 不同的是,SortedSet 中的元素会自动按内部顺序排序。这意味着当你遍历 SortedSet 中的元素时,它们会按照排序后的顺序被依次访问。
TreeSet:SortedSet 的实现类
Java Collections API 中唯一实现了 SortedSet 接口的类是 java.util.TreeSet。虽然 java.util.concurrent 包中也提供了该接口的实现,但本教程暂不涉及并发工具类。
创建一个 TreeSet
以下是如何创建一个 TreeSet 实例的示例:
SortedSet sortedSet = new TreeSet();
使用 Comparator 创建 TreeSet
你可以向 TreeSet 的构造函数传入一个 Comparator(java.util.Comparator 的实现),用于自定义元素的排序规则。例如:
Comparator comparator = new MyComparatorImpl();
SortedSet sortedSet = new TreeSet(comparator);
排序规则(Sort Order)
默认情况下,SortedSet 会使用元素的自然排序顺序。要使 SortedSet 能够判断元素的自然顺序,这些元素必须实现 java.lang.Comparable 接口。
如果元素没有实现 Comparable 接口,则它们没有自然顺序。此时,你必须在创建 SortedSet 时传入一个 Comparator。TreeSet 的构造函数支持传入 Comparator,例如:
Comparator comparator = new MyComparator();
SortedSet sortedSet = new TreeSet(comparator);
升序 vs 降序
默认情况下,SortedSet 的元素以升序遍历,即从“最小”到“最大”。但你也可以通过 TreeSet.descendingIterator() 方法以降序遍历元素。例如:
TreeSet treeSet = new TreeSet();
treeSet.add("one");
treeSet.add("two");
treeSet.add("three");
Iterator iterator = treeSet.descendingIterator();
while(iterator.hasNext()) {
String element = (String) iterator.next();
System.out.println(element);
}
获取使用的 Comparator
如果你在创建 SortedSet 时传入了 Comparator,可以通过 comparator() 方法获取它:
Comparator comparator = sortedSet.comparator();
基本操作
添加元素
向 SortedSet 添加元素的方式与普通 Set 相同,使用 add() 方法:
SortedSet sortedSet = new TreeSet();
sortedSet.add("one");
删除元素
通过 remove() 方法删除指定元素:
sortedSet.remove("one");
获取第一个元素
调用 first() 方法可获取按排序顺序的第一个元素:
Object firstElement = sortedSet.first();
获取最后一个元素
调用 last() 方法可获取按排序顺序的最后一个元素:
Object lastElement = sortedSet.last();
遍历 SortedSet
遍历方式与普通 Set 相同,使用 iterator() 方法:
SortedSet sortedSet = new TreeSet();
sortedSet.add("one");
sortedSet.add("two");
sortedSet.add("three");
Iterator iterator = sortedSet.iterator();
while(iterator.hasNext()) {
String element = (String) iterator.next();
System.out.println(element);
}
子集操作
获取头集(Head Set)
headSet(E toElement) 方法返回一个新的 SortedSet,包含所有小于给定元素的元素(按排序顺序):
SortedSet sortedSet = new TreeSet();
sortedSet.add("a");
sortedSet.add("b");
sortedSet.add("c");
sortedSet.add("d");
sortedSet.add("e");
SortedSet headSet = sortedSet.headSet("c");
// headSet 包含 "a", "b"
获取尾集(Tail Set)
tailSet(E fromElement) 方法返回一个新的 SortedSet,包含所有大于或等于给定元素的元素:
SortedSet tailSet = sortedSet.tailSet("c");
// tailSet 包含 "c", "d", "e"
获取子集(Subset)
subSet(E fromElement, E toElement) 方法返回一个新 SortedSet,包含所有大于等于 fromElement 且小于 toElement 的元素:
SortedSet subSet = sortedSet.subSet("c", "e");
// subSet 包含 "c", "d"
泛型 SortedSet
声明 SortedSet 变量时可以指定泛型类型。例如:
SortedSet<String> sortedSet = new TreeSet<>();
这样,该 SortedSet 只能包含 String 类型的元素。从集合中取出元素时无需强制类型转换:
SortedSet<String> sortedSet = new TreeSet<>();
sortedSet.add("one");
sortedSet.add("two");
sortedSet.add("three");
Iterator<String> iterator = sortedSet.iterator();
while(iterator.hasNext()) {
String element = iterator.next(); // 无需强制转换
System.out.println(element);
}