Guava中Ordering简介
Contents
1. 概述
在本文中,我们将研究 Guava 库中的Ordering类。
Ordering类实现了Comparator接口,并为我们提供了一个有用的流式 API 来创建和链接比较器。
作为一个简短的旁注,还值得看看新的Comparator.comparing() API——它提供了类似的功能;这是一个使用该 API的实际示例 。
2. 创建Ordering
Ordering有一个有用的 builder 方法,它返回一个适当的实例,该实例可用于集合上的sort()方法或需要Comparator实例的任何其他地方。
我们可以通过执行方法natural() 创建自然顺序实例:
List<Integer> integers = Arrays.asList(3, 2, 1);
integers.sort(Ordering.natural());
assertEquals(Arrays.asList(1,2,3), integers);
假设我们有一个Person对象的集合:
class Person {
private String name;
private Integer age;
// standard constructors, getters
}
我们想按age字段对这些对象的列表进行排序。我们可以创建我们的自定义Ordering,通过扩展它来做到这一点:
List<Person> persons = Arrays.asList(new Person("Michael", 10), new Person("Alice", 3));
Ordering<Person> orderingByAge = new Ordering<Person>() {
@Override
public int compare(Person p1, Person p2) {
return Ints.compare(p1.age, p2.age);
}
};
persons.sort(orderingByAge);
assertEquals(Arrays.asList(new Person("Alice", 3), new Person("Michael", 10)), persons);
然后我们可以使用orderingByAge并将其传递给*sort()*方法。
3. 链式排序
这个类的一个有用的特性是我们可以链接不同的排序方式。假设我们有一个人的集合,我们想按年龄字段对其进行排序,并在列表的开头有空的年龄字段值:
List<Person> persons = Arrays.asList(
new Person("Michael", 10),
new Person("Alice", 3),
new Person("Thomas", null));
Ordering<Person> ordering = Ordering
.natural()
.nullsFirst()
.onResultOf(new Function<Person, Comparable>() {
@Override
public Comparable apply(Person person) {
return person.age;
}
});
persons.sort(ordering);
assertEquals(Arrays.asList(
new Person("Thomas", null),
new Person("Alice", 3),
new Person("Michael", 10)), persons);
这里要注意的重要一点是执行特定Ordering的顺序——顺序是从右到左。所以首先执行*onResultOf()*并且该方法提取我们想要比较的字段。
然后,执行nullFirst()比较器。因此,生成的排序集合将有一个Person对象,该对象在列表的开头有一个null作为年龄字段。
在排序过程结束时,使用方法*natural()*指定的自然排序比较年龄字段。