Guide to Guava’s Ordering – Guava’的订购指南

最后修改: 2017年 2月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we will look at Ordering class from the Guava library.

在这篇文章中,我们将看看Guava库中的Orderingclass。

The Ordering class implements the Comparator interface and gives us a useful fluent API for creating and chaining comparators.

Ordering 类实现了Comparator接口,为我们提供了一个有用的流畅的API来创建和连锁比较器。

As a quick sidenote, it’s also worth looking at the new Comparator.comparing() API – which provides similar functionality; here’s a practical example using that API.

作为一个快速的附带说明,也值得看看新的Comparator.comparing() API – 它提供了类似的功能;这里有一个使用该API的实际例子

2. Creating Ordering

2.创建订购

Ordering has a useful builder method that returns a proper instance that can be used in a sort() method on collections or anywhere else where an instance of Comparator is needed.

Ordering有一个有用的构建方法,它可以返回一个适当的实例,可以在集合的sort()方法中使用,或者在其他需要Comparator实例的地方。

We can create natural order instance by executing method natural():

我们可以通过执行方法natural()来创建自然秩序实例:

List<Integer> integers = Arrays.asList(3, 2, 1);

integers.sort(Ordering.natural());

assertEquals(Arrays.asList(1,2,3), integers);

Let’s say that we have a collection of Person objects:

比方说,我们有一个Person 对象的集合。

class Person {
    private String name;
    private Integer age;
    
    // standard constructors, getters
}

And we want to sort a list of such objects by age field. We can create our custom Ordering that will do exactly that by extending it:

而我们想按年龄字段对这类对象的列表进行排序。我们可以创建我们的自定义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);

Then we can use our orderingByAge and pass it to sort() method.

然后我们可以使用我们的orderingByAge ,并将其传递给sort() 方法。

3. Chaining Orderings

3.链接排序

One useful feature of this class is that we can chain different ways of Ordering. Let’s say we have a collection of persons and we want to sort it by age field and have null age field values at the beginning of a list:

这个类的一个有用的特点是,我们可以用不同的方式进行排序。假设我们有一个人的集合,我们想通过年龄字段来排序,并且在列表的开头有空的年龄字段值。

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

The important thing to notice here is an order in which particular Orderings are executed – order is from right to left. So firstly onResultOf() is executed and that method extracts the field that we want to compare.

这里需要注意的是特定的Orderings被执行的顺序–顺序是从右到左。所以首先onResultOf()被执行,该方法提取了我们想要比较的字段。

Then, nullFirst() comparator is executed. Because of that, the resulting sorted collection will have a Person object that has a null as an age field at the beginning of the list.

然后,nullFirst()比较器被执行。因为这样,产生的排序集合将有一个Person 对象,它的null 作为age字段在列表的开头。

At the end of the sorting process, age fields are compared using natural ordering as specified using method natural().

在排序过程结束时,年龄字段将使用自然排序进行比较,具体方法为natural()

4. Conclusion

4.总结

In this article, we looked at Ordering class from Guava library that allows us to create more fluent and elegant Comparators. We created our custom Ordering, we used predefined ones from the API, and we chained them to achieve more custom order.

在这篇文章中,我们看了Guava库中的Ordering类,它允许我们创建更流畅和优雅的比较器s。我们创建了自定义的Ordering,我们使用了来自API的预定义的Ordering,并且我们将它们连锁起来以实现更多的自定义顺序。

The implementation of all these examples and code snippets can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

所有这些例子和代码片段的实现都可以在GitHub项目中找到–这是一个基于Maven的项目,所以应该很容易按原样导入和运行。