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, поэтому его легко импортировать и запускать как есть.