SortedSet接口
SortedSet是一個(gè)Set,它按升序維護(hù)其元素,根據(jù)元素的自然順序或根據(jù)SortedSet創(chuàng)建時(shí)提供的Comparator進(jìn)行排序,除了常規(guī)的Set操作外,SortedSet接口還提供以下操作:
范圍視圖 — 允許對(duì)已排序集進(jìn)行任意范圍操作。
端點(diǎn) — 返回有序集合中的第一個(gè)或最后一個(gè)元素。
比較器訪問 — 返回用于對(duì)集合進(jìn)行排序的Comparator(如果有)。
下面是SortedSet接口的代碼。
public interface SortedSetSet操作extends Set { // Range-view SortedSet subSet(E fromElement, E toElement); SortedSet headSet(E toElement); SortedSet tailSet(E fromElement); // Endpoints E first(); E last(); // Comparator access Comparator super E> comparator(); }
SortedSet從Set繼承的操作在有序集和普通集上的行為相同,但有兩個(gè)例外:
Iterator操作返回的iterator按順序遍歷有序集。
toArray返回的數(shù)組按順序包含有序集的元素。
雖然接口不保證它,但Java平臺(tái)的SortedSet實(shí)現(xiàn)的toString方法按順序返回包含有序集的所有元素的字符串。
標(biāo)準(zhǔn)構(gòu)造函數(shù)按照慣例,所有通用Collection實(shí)現(xiàn)都提供了一個(gè)帶有Collection的標(biāo)準(zhǔn)轉(zhuǎn)換構(gòu)造函數(shù),SortedSet實(shí)現(xiàn)也不例外,在TreeSet中,此構(gòu)造函數(shù)創(chuàng)建一個(gè)實(shí)例,根據(jù)其自然順序?qū)ζ湓剡M(jìn)行排序,這可能是一個(gè)錯(cuò)誤,最好動(dòng)態(tài)檢查以查看指定的集合是否是SortedSet實(shí)例,如果是,則根據(jù)相同的標(biāo)準(zhǔn)(比較器或自然排序)對(duì)新TreeSet進(jìn)行排序。因?yàn)?b>TreeSet采用了它所采用的方法,所以它還提供了一個(gè)構(gòu)造函數(shù),它接受一個(gè)SortedSet并返回一個(gè)新的TreeSet,它包含根據(jù)相同標(biāo)準(zhǔn)排序的相同元素。請(qǐng)注意,它是參數(shù)的編譯時(shí)類型,而不是其運(yùn)行時(shí)類型,它確定調(diào)用這兩個(gè)構(gòu)造函數(shù)中的哪一個(gè)(以及是否保留了排序條件)。
按照慣例,SortedSet實(shí)現(xiàn)還提供了一個(gè)構(gòu)造函數(shù),它接受一個(gè)Comparator并返回一個(gè)根據(jù)指定的Comparator排序的空集,如果將null傳遞給此構(gòu)造函數(shù),則返回一個(gè)集合,該集合根據(jù)其自然順序?qū)ζ湓剡M(jìn)行排序。
范圍視圖操作范圍視圖操作有點(diǎn)類似于List接口提供的操作,但有一個(gè)很大的區(qū)別,即使直接修改了后備排序集,排序集的范圍視圖仍然有效,這是可行的,因?yàn)橛行蚣姆秶晥D的端點(diǎn)是元素空間中的絕對(duì)點(diǎn),而不是后備集合中的特定元素,如列表的情況。排序集的范圍視圖實(shí)際上只是集合的任何部分位于元素空間的指定部分中的窗口,對(duì)范圍視圖的更改將寫回到后備排序集,反之亦然,因此,與列表上的范圍視圖不同,可以在很長(zhǎng)一段時(shí)間內(nèi)對(duì)已排序的集使用范圍視圖。
排序集提供三種范圍視圖操作,第一個(gè)subSet采用兩個(gè)端點(diǎn),如subList,而不是索引,端點(diǎn)是對(duì)象,必須與有序集合中的元素相比較,使用Set的Comparator或其元素的自然順序,無論Set使用哪個(gè)自定義,與subList一樣,范圍是半開放的,包括其低端點(diǎn)但不包括高端點(diǎn)。
因此,下面的代碼行告訴你,包含在名為dictionary的字符串SortedSet中,“doorbell”和“pickle”之間有多少單詞,包括“doorbell”,但不包括“pickle”:
int count = dictionary.subSet("doorbell", "pickle").size();
以類似的方式,以下單行刪除以字母f開頭的所有元素。
dictionary.subSet("f", "g").clear();
類似的技巧可以用來打印一個(gè)表格,告訴你每個(gè)字母開頭有多少個(gè)單詞。
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()); }
假設(shè)你要查看包含其兩個(gè)端點(diǎn)的封閉間隔,而不是開放的間隔,如果元素類型允許計(jì)算元素空間中給定值的后繼,則僅從subSet的lowEndpoint請(qǐng)求到successor(highEndpoint),雖然它并不完全明顯,但String的自然排序中的字符串s的后繼是s + "