(Guava 译文系列)排序
排序
示例
1 | assertTrue(byLengthOrdering.reverse().isOrdered(list)); |
简述
Ordering
是
Guava
的“流式”Comparator
类。它能够用于构建复杂的比较器,并且能应用于集合对象上。
一个Ordering
实例的核心仅仅是一个特殊的Comparator
实例。Ordering
简单的取用一些依赖Comparator
的静态方法(例如
Collections.max
)将之改造为实例方法。此外,Ordering
类还提供了链式方法来改进、增强现有的比较器。
创建
通用的排序实例可由静态方法提供:
方法 | 描述 |
---|---|
natural |
使用正常序列的 Comparable 类型 |
usingToString |
以字典序对对象的字符串表示(由toString() 返回)进行排序 |
将一个现存的Comparator
来构造Ordering
,最简单的方法是使用Ordering.from(Comparator)
。
但是更通用的构造一个自定义Ordering
的方法是完全跳过Comparator
而直接扩展Ordering
的抽象类:
1 | Ordering<String> byLengthOrdering = new Ordering<String>() { |
链式调用
一个给定的Ordering
可以被包装并获取派生的Ordering
。如下是一些最常用的变体:
方法 | 描述 |
---|---|
reverse() |
返回反向排序 |
nullsFirst() |
返回一个新的Ordering ,会将 null 对象至于 non- null
对象之前,如果没有 null
对象,则表现为与原始Ordering 的行为一致。类似的可见nullsLast |
compound(Comparator) |
返回一个专用的Ordering ,当遇到相等情况时可进行进一步比较 |
lexicographical() |
返回可对 iterables 的元素按照字典序排序的Ordering |
onResultOf(Function) |
返回一个Ordering ,对被比较值先执行
Function,对返回值按初始Ordering 进行排序 |
举例说明,假如你想要构造一个下述类的比较器: 1
2
3
4class Foo {
String sortedBy;
int notSortedBy;
}sortBy
成员。以下是一个建立在链式调用方法上的解决方案:
1
2
3
4
5Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<Foo, String>() {
public String apply(Foo foo) {
return foo.sortedBy;
}
});Ordering
进行读取时,按从右至左倒序工作。以上例子通过读取sortedBy
成员变量值来对Foo
进行排序,首先将所有为
null
的sortedBy
移动至最前面,然后对剩下的进行字符串的正常排序。之所以出现倒序,是因为每一个链式调用,都将上一个Ordering
进行封装成为一个新的Ordering
。
(对“倒序”规则的一个例外:当链式调用涉及compound
时,读取从左至右。为了避免混淆,不要将compound
与其他类型的链式调用一起使用。)
超过几个调用的调用链将会难以理解。就像上述例子一样,我们推荐限制链式调用的调用长度不大于
3 个。即使这样,你也许会期望进一步简化,将 中间对象 -
如Function
实例 - 分离出来,就像这样: 1
Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction);
应用
Guava
提供了许多方法来通过Ordering
对值或集合进行操作或检查。我们在以下列出了最常用的:
方法 | 描述 | 类似的 |
---|---|---|
greatestOf(Iterable iterable, int k) |
返回指定 iterable
中k 个最大的元素,按照该Ordering 从大到小排序 |
leastOf |
isOrdered(Iterable) |
测试指定的 Iterable
是否按照Ordering 非递减排序。 |
isStrictlyOrdered |
sortedCopy(Iterable) |
返回一个对指定元素进行排序的副本List |
immutableSortedCopy |
min(E, E) |
按照Ordering 返回输入参数中较小的一个。假如相等,则返回第一个 |
max(E, E) |
min(E, E, E, E...) |
按照Ordering 返回输入参数中较小的一个。假如存在多个最小值,则返回第一个 |
max(E, E, E, E...) |
min(Iterable) |
返回指定Iterable 中最小的元素。假如Iterable 为空则抛出NoSuchElementException 异常 |
max(Iterable) ,
min(Iterator) ,
max(Iterator) |