β

[集合框架] SortedSet 接口

Aptusource.orgAptusource.org 223 阅读

SortedSet 是 Set 的一个子类,它支持 Set 中的元素排序,排序规则按照自然排序或者按照创建 SortedSet 时设置的 Comparator 进行排序。除了 Set 接口中的方法外,SortedSet 接口还提供了下面的操作:

下面是 SortedSet 的接口声明:

public interface SortedSet<E> extends Set<E> {
    // Range-view
    SortedSet<E> subSet(E fromElement, E toElement);
    SortedSet<E> headSet(E toElement);
    SortedSet<E> tailSet(E fromElement);

    // Endpoints
    E first();
    E last();

    // Comparator access
    Comparator<? super E> comparator();
}

继承自 Set 的操作

SortedSet 继承自 Set 接口,它的行为大部分和 Set 一致,除了下面两个例外:

接口无法保证 toString 方法会返回有顺序的元素列表。

标准构造方法

按照惯例,所有的 Collection 实现都需要提供一个带有参数的构造方法,在参数中传入另一个 Collection 来初始化新创建的 Collection。当然 SortedSet 的实现也不例外。TreeSet 的构造方法就可以传入 Collection 来进行初始化,并且存储的元素会按照它们的自然排序。这么做可能会有带来一些问题,因此,TreeSet 最好的实现是判断传入的 Collection 是否是 SortedSet 类型,如果是,那么将按照传入的 SortedSet 带来的排序规则进行排序(自然排序或 Comparator)。TreeSet 正是那么做的,它同时提供了一个带 SortedSet 参数的构造方法,创建 TreeSet 的时候,新创建的 TreeSet 的排序规则与参数中的 SortedSet 保持一致。

SortedSet 的实现按照惯例还需要有一个带有 Comparator 参数的构造方法。如果调用这个构造方法,将会返回一个按照指定 Comparator 排序的空 SortedSet,如果指定的 Comparator 为 null,那么返回的 SortedSet 将按照自然排序。

范围操作

SortedSet 中的范围操作有点类似 List 中的范围操作。但是,有一个最大的差别。SortedSet 返回了 sub-set (调用 subSet 方法返回的 Set)后,即使使用其它方法改变了 SortedSet 的内容,sub-set 也依然合法,这一点和 List 不一样。这是因为 SortedSet 范围操作的端点是元素的绝对指针而不是元素本身。改变 sub-set 将会影响到 SortedSet,反过来也一样。因此,我们在代码中可以长时间保留 sub-set 而不仅仅用于临时变量,这一点和 List 不同。

SortedSet 提供了三种范围操作。首先是 subSet,调用它需要设置两个参数,表示 sub-set 的两个端点。这两个端点是 set 中的元素而不是索引(这点和 subList 不同),这两个对象必须是可比较对象,无论使用 Comparator 还是自然排序,它们都必须可比较。类似 subList,subSet 方法也是半开区间,包含低的端点不包含高的端点。

因此,下面的语句将告诉你 doorbell 到 pickle 之间有多少个单词,包含 doorbell 不包含 pickle:

int count = dictionary.subSet("doorbell", "pickle").size();

同样,下面的代码将删除从字母 f 开始的元素:

dictionary.subSet("f", "g").clear();

下面的代码将打印出 Set 中包含每个字母的个数:

for (char ch = 'a'; ch <= 'z'; ) {
    String from = String.valueOf(ch++);
    String to = String.valueOf(ch);
    System.out.println(from + ": " + dictionary.subSet(from, to).size());
}

假设你要查看闭区间中的 String 元素,意味着元素要包括两个端点。假设有一个 String s,那么可以在  s 后添加 “\0”,这相当于在 s 后面添加了 null 字符。在 SortedSet 中 s + “\0″ 的位置在 s 之后,因此用这个技术来设置端点将包含 s 本身。

下面的代码将计算 doorbell 到 pickle 之间有多少个单词,包含 doorbell  和 pickle:

count = dictionary.subSet("doorbell", "pickle\0").size();

同样的技术也可用于开区间,它将不包含两个端点。下面的代码将计算 doorbell 到 pickle 之间有多少个单词,不包含 doorbell  和 pickle:

count = dictionary.subSet("doorbell\0", "pickle").size();

SortedSet 还有两个方法 headSet 和 tailSet,这两个方法都带有一个参数。第一个方法用于获取从 set 第一个元素到指定元素的 sub-set,第二个方法用于获取从指定元素到最后一个元素的 sub-set。因此下面的代码得到的字母是 a-m 和 n-z:

SortedSet<String> volume1 = dictionary.headSet("n");
SortedSet<String> volume2 = dictionary.tailSet("n");

端点操作

SortedSet 还有两个方法 first 和 last,用于返回 set 的第一个和最后一个元素。

下面的代码将获得指定元素之前的所有元素的最后一个元素:

Object predecessor = ss.headSet(o).last();

获取比较器

SortedSet 还提供了 comparator 方法用于获取 Comparator 对象,如果返回值是 null 表示 set 中的元素按照自然排序。

作者:Aptusource.orgAptusource.org
最好的 Java 技术博客
原文地址:[集合框架] SortedSet 接口, 感谢原作者分享。