Java™ 教程(SortedSet接口)

SortedSet接口

SortedSet是一個Set,它按升序維護其元素,根據元素的天然順序或根據SortedSet建立時提供的Comparator進行排序,除了常規的Set操做外,SortedSet接口還提供如下操做:html

  • 範圍視圖 — 容許對已排序集進行任意範圍操做。
  • 端點 — 返回有序集合中的第一個或最後一個元素。
  • 比較器訪問 — 返回用於對集合進行排序的Comparator(若是有)。

下面是SortedSet接口的代碼。java

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操做

SortedSetSet繼承的操做在有序集和普通集上的行爲相同,但有兩個例外:segmentfault

  • Iterator操做返回的iterator按順序遍歷有序集。
  • toArray返回的數組按順序包含有序集的元素。

雖然接口不保證它,但Java平臺的SortedSet實現的toString方法按順序返回包含有序集的全部元素的字符串。api

標準構造函數

按照慣例,全部通用Collection實現都提供了一個帶有Collection的標準轉換構造函數,SortedSet實現也不例外,在TreeSet中,此構造函數建立一個實例,根據其天然順序對其元素進行排序,這多是一個錯誤,最好動態檢查以查看指定的集合是不是SortedSet實例,若是是,則根據相同的標準(比較器或天然排序)對新TreeSet進行排序。由於TreeSet採用了它所採用的方法,因此它還提供了一個構造函數,它接受一個SortedSet並返回一個新的TreeSet,它包含根據相同標準排序的相同元素。請注意,它是參數的編譯時類型,而不是其運行時類型,它肯定調用這兩個構造函數中的哪個(以及是否保留了排序條件)。數組

按照慣例,SortedSet實現還提供了一個構造函數,它接受一個Comparator並返回一個根據指定的Comparator排序的空集,若是將null傳遞給此構造函數,則返回一個集合,該集合根據其天然順序對其元素進行排序。oracle

範圍視圖操做

範圍視圖操做有點相似於List接口提供的操做,但有一個很大的區別,即便直接修改了後備排序集,排序集的範圍視圖仍然有效,這是可行的,由於有序集的範圍視圖的端點是元素空間中的絕對點,而不是後備集合中的特定元素,如列表的狀況。排序集的範圍視圖實際上只是集合的任何部分位於元素空間的指定部分中的窗口,對範圍視圖的更改將寫回到後備排序集,反之亦然,所以,與列表上的範圍視圖不一樣,能夠在很長一段時間內對已排序的集使用範圍視圖。函數

排序集提供三種範圍視圖操做,第一個subSet採用兩個端點,如subList,而不是索引,端點是對象,必須與有序集合中的元素相比較,使用SetComparator或其元素的天然順序,不管Set使用哪一個自定義,與subList同樣,範圍是半開放的,包括其低端點但不包括高端點。code

所以,下面的代碼行告訴你,包含在名爲dictionary的字符串SortedSet中,「doorbell」和「pickle」之間有多少單詞,包括「doorbell」,但不包括「pickle」:htm

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

以相似的方式,如下單行刪除以字母f開頭的全部元素。對象

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

相似的技巧能夠用來打印一個表格,告訴你每一個字母開頭有多少個單詞。

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());
}

假設你要查看包含其兩個端點的封閉間隔,而不是開放的間隔,若是元素類型容許計算元素空間中給定值的後繼,則僅從subSetlowEndpoint請求到successor(highEndpoint),雖然它並不徹底明顯,但String的天然排序中的字符串s的後繼是s + "\0" — 也就是說,附加了空字符的s

所以,下面的單行告訴你「doorbell」和「pickle」之間有多少單詞,包括doorbellpickle,都包含在字典中。

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

能夠使用相似的技術來查看不包含端點的開放間隔,從lowEndpointhighEndpoint的開放間隔視圖是從successor(lowEndpoint)highEndpoint的半開放間隔,使用如下內容計算「doorbell」和「pickle」之間的單詞數,不包括二者。

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

SortedSet接口包含另外兩個範圍視圖操做 — headSettailSet,二者都採用單個Object參數,前者返回後備SortedSet的初始部分的視圖,直到但不包括指定的對象,後者返回後備SortedSet的最後一部分的視圖,從指定的對象開始,一直到後備SortedSet的末尾,所以,如下代碼容許你將字典視爲兩個不相交的卷(a-mn-z)。

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

端點操做

SortedSet接口包含返回有序集合中第一個和最後一個元素的操做,絕不奇怪被稱爲firstlast,除了它們的明顯用途以外,last還容許解決SortedSet接口中的不足。你想對SortedSet作的一件事就是進入Set的內部並向前或向後迭代,從內部向前迭代很容易:只需獲取一個tailSet並迭代它,不幸的是,沒有簡單的方法能夠倒退。

如下語法得到的元素空間中小於指定對象o的第一個元素。

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

這是從排序集內部的一個點向後移動一個元素的好方法,它能夠重複應用以向後迭代,但這是很是低效的,須要查找返回的每一個元素。

Comparator訪問

SortedSet接口包含一個名爲comparator的訪問器方法,它返回用於對集合進行排序的Comparator,若是集合根據其元素的天然順序排序,則爲null,提供此方法以即可以將排序的集合複製到具備相同排序的新排序集合中,它由前面描述的SortedSet構造函數使用。


上一篇:對象排序

相關文章
相關標籤/搜索