使用 Set、SortedSet 和 NavigableSet 扩展集合
探索 Set 接口
Set 接口没有为 Collection 接口带来任何新方法。集合框架为您提供了一个 Set 接口的简单实现:HashSet。在内部,HashSet 包装了一个 HashMap 实例,该类将在后面介绍,它充当 HashSet 的代理。
正如您已经看到的,Set 为 Collection 带来的好处是它禁止重复。与 List 接口相比,您失去的是元素以无特定顺序存储。您几乎不可能以与添加到集合中的顺序相同的顺序遍历它们。
您可以在以下示例中看到这一点
List<String> strings = List.of("one", "two", "three", "four", "five", "six");
Set<String> set = new HashSet<>();
set.addAll(strings);
set.forEach(System.out::println);
运行此代码将产生以下结果
six
four
one
two
three
five
一些 Set 的实现会在您遍历其元素时为您提供相同的顺序,但由于这不是保证的,因此您的代码不应依赖于此。
使用 SortedSet 扩展 Set
Set 的第一个扩展是 SortedSet 接口。 SortedSet 接口根据特定的比较逻辑对其元素进行排序。集合框架为您提供了一个 SortedSet 实现,称为 TreeSet。
正如您已经看到的,您可以在构建 TreeSet 时提供比较器,或者为放入 TreeSet 的元素实现 Comparable 接口。如果您同时执行这两项操作,则比较器优先。
first()和last()返回集合中最小的和最大的元素headSet(toElement)和tailSet(fromElement)返回包含小于toElement或大于fromElement的元素的子集subSet(fromElement, toElement)为您提供fromElement和toElement之间元素的子集。
toElement 和 fromElement 不必是主集合的元素。如果它们是,则 toElement 不包含在结果中,而 fromElement 包含在结果中,遵循通常的约定。
请考虑以下示例
SortedSet<String> strings = new TreeSet<>(Set.of("a", "b", "c", "d", "e", "f"));
SortedSet<String> subSet = strings.subSet("aa", "d");
System.out.println("sub set = " + subSet);
运行此代码将为您提供以下结果
sub set = [b, c]
这些方法返回的三个子集是主集合的视图。不会进行任何复制,这意味着您对这些子集进行的任何更改都将反映在集合中,反之亦然。
您可以通过这些子集删除或添加主集合中的元素。不过,您需要注意一点。这三个子集会记住它们构建的限制。出于一致性原因,通过子集添加超出其限制的元素是非法的。例如,如果您获取一个 headSet 并尝试添加大于 toElement 的元素,那么您将得到一个 IllegalArgumentException。
使用 NavigableSet 扩展 SortedSet
Java SE 6 引入了 SortedSet 的扩展,并添加了更多方法。事实证明,TreeSet 类已进行改造以实现 NavigableSet。因此,您可以对这两个接口使用相同的类。
一些方法被 NavigableSet 重载。
添加了其他方法。
ceiling(element)和floor(element)返回小于或等于提供的element的最大元素,或大于或等于提供的element的最小元素。如果没有这样的元素,则返回nulllower(element)和higher(element)返回小于提供的element的最大元素,或大于提供的element的最小元素。如果没有这样的元素,则返回null。pollFirst()和pollLast()返回并删除集合中最小的或最大的元素。
此外,NavigableSet 还允许您以降序遍历其元素。有两种方法可以做到这一点。
- 您可以调用
descendingIterator():它为您提供一个常规的Iterator,它以降序遍历集合。 - 您还可以调用
descendingSet()。您得到的返回值是另一个NavigableSet,它是此集合的视图,让您感觉您拥有的是同一个集合,只是以相反的顺序排序。
以下示例演示了这一点。
NavigableSet<String> sortedStrings = new TreeSet<>(Set.of("a", "b", "c", "d", "e", "f"));
System.out.println("sorted strings = " + sortedStrings);
NavigableSet<String> reversedStrings = sortedStrings.descendingSet();
System.out.println("reversed strings = " + reversedStrings);
运行此代码将为您提供以下结果
sorted strings = [a, b, c, d, e, f]
reversed strings = [f, e, d, c, b, a]
上次更新: 2021 年 9 月 14 日