Перейти к основному содержимому

Руководство по заказу гуавы

· 3 мин. чтения

1. Обзор

В этой статье мы рассмотрим класс Ordering из библиотеки Guava.

Класс Ordering реализует интерфейс Comparator и предоставляет полезный гибкий API для создания и связывания компараторов.

В качестве быстрого примечания также стоит взглянуть на новый API Comparator.comparing() , который обеспечивает аналогичную функциональность; вот практический пример использования этого API.

2. Создание заказа

Ordering имеет полезный метод построения, который возвращает правильный экземпляр, который можно использовать в методе 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
}

И мы хотим отсортировать список таких объектов по возрастному полю. Мы можем создать наш пользовательский 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 с нулевым значением в качестве поля возраста в начале списка.

В конце процесса сортировки поля возраста сравниваются с использованием естественного порядка, указанного с помощью метода natural() .

4. Вывод

В этой статье мы рассмотрели класс Ordering из библиотеки Guava, который позволяет нам создавать более плавные и элегантные компараторы . Мы создали наш пользовательский порядок, мы использовали предопределенные из API и связали их в цепочку, чтобы добиться более индивидуального порядка.

Реализацию всех этих примеров и фрагментов кода можно найти в проекте GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.