排序器[Ordering]是 Guava 流暢風(fēng)格比較器[Comparator]的實現(xiàn),它可以用來為構(gòu)建復(fù)雜的比較器,以完成集合排序的功能。
從實現(xiàn)上說,Ordering 實例就是一個特殊的 Comparator 實例。Ordering 把很多基于 Comparator 的靜態(tài)方法(如 Collections.max)包裝為自己的實例方法(非靜態(tài)方法),并且提供了鏈式調(diào)用方法,來定制和增強現(xiàn)有的比較器。
創(chuàng)建排序器:常見的排序器可以由下面的靜態(tài)方法創(chuàng)建
方法 | 描述 |
natural() | 對可排序類型做自然排序,如數(shù)字按大小,日期按先后排序 |
usingToString() | 按對象的字符串形式做字典排序[lexicographical ordering] |
from(Comparator) | 把給定的 Comparator 轉(zhuǎn)化為排序器 |
實現(xiàn)自定義的排序器時,除了用上面的 from 方法,也可以跳過實現(xiàn) Comparator,而直接繼承 Ordering:
Ordering<String> byLengthOrdering = new Ordering<String>() {
public int compare(String left, String right) {
return Ints.compare(left.length(), right.length());
}
};
鏈式調(diào)用方法:通過鏈式調(diào)用,可以由給定的排序器衍生出其它排序器
方法 | 描述 |
reverse() | 獲取語義相反的排序器 |
nullsFirst() | 使用當(dāng)前排序器,但額外把 null 值排到最前面。 |
nullsLast() | 使用當(dāng)前排序器,但額外把 null 值排到最后面。 |
compound(Comparator) | 合成另一個比較器,以處理當(dāng)前排序器中的相等情況。 |
lexicographical() | 基于處理類型 T 的排序器,返回該類型的可迭代對象 Iterable<T>的排序器。 |
onResultOf(Function) | 對集合中元素調(diào)用 Function,再按返回值用當(dāng)前排序器排序。 |
例如,你需要下面這個類的排序器。
class Foo {
@Nullable String sortedBy;
int notSortedBy;
}
考慮到排序器應(yīng)該能處理 sortedBy 為 null 的情況,我們可以使用下面的鏈式調(diào)用來合成排序器:
Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<Foo, String>() {
public String apply(Foo foo) {
return foo.sortedBy;
}
});
當(dāng)閱讀鏈式調(diào)用產(chǎn)生的排序器時,應(yīng)該從后往前讀。上面的例子中,排序器首先調(diào)用 apply 方法獲取 sortedBy 值,并把 sortedBy 為 null 的元素都放到最前面,然后把剩下的元素按 sortedBy 進行自然排序。之所以要從后往前讀,是因為每次鏈式調(diào)用都是用后面的方法包裝了前面的排序器。
注:用 compound 方法包裝排序器時,就不應(yīng)遵循從后往前讀的原則。為了避免理解上的混亂,請不要把 compound 寫在一長串鏈式調(diào)用的中間,你可以另起一行,在鏈中最先或最后調(diào)用 compound。
超過一定長度的鏈式調(diào)用,也可能會帶來閱讀和理解上的難度。我們建議按下面的代碼這樣,在一個鏈中最多使用三個方法。此外,你也可以把 Function 分離成中間對象,讓鏈式調(diào)用更簡潔緊湊。
Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction)
運用排序器:Guava 的排序器實現(xiàn)有若干操縱集合或元素值的方法
方法 | 描述 | 另請參見 |
greatestOf(Iterable iterable, int k) | 獲取可迭代對象中最大的k個元素。 | leastOf |
isOrdered(Iterable) | 判斷可迭代對象是否已按排序器排序:允許有排序值相等的元素。 | isStrictlyOrdered |
sortedCopy(Iterable) | 判斷可迭代對象是否已嚴格按排序器排序:不允許排序值相等的元素。 | immutableSortedCopy |
min(E, E) | 返回兩個參數(shù)中最小的那個。如果相等,則返回第一個參數(shù)。 | max(E, E) |
min(E, E, E, E...) | 返回多個參數(shù)中最小的那個。如果有超過一個參數(shù)都最小,則返回第一個最小的參數(shù)。 | max(E, E, E, E...) |
min(Iterable) | 返回迭代器中最小的元素。如果可迭代對象中沒有元素,則拋出 NoSuchElementException。 | max(Iterable), min(Iterator), max(Iterator) |