Сортировка списка объектов по полю в Java
Java предоставляет несколько способов сортировки списка. В этой статье мы покажем, как отсортировать список объектов по полю.
Список объектов
В наших примерах мы будем использовать следующий User
класс:
package com.example.demo;
import java.util.Date;
public class User { private long id; private String email; private Date createdOn;
// other getters and setters omitted
public Date getCreatedOn() { return createdOn; }
public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; } }
Предположим, у нас есть служебный метод, который возвращает список всех пользователей:
List<User> users = userService.getAllUsers();
Сортировать список объектов по полю
Итак, у нас есть список пользователей, и мы хотим отсортировать их по createdDate.
Давайте рассмотрим несколько различных подходов и рассмотрим преимущества и недостатки каждого из них.
Вариант 1: Collections.sort () с Comparable
Мы можем использовать интерфейс Comparable для определения критериев сортировки по умолчанию для класса.
Для этого требуется реализовать метод compareTo (), как показано в строках 20–26 ниже:
package com.example.demo;
import java.util.Date;
public class User implements Comparable<User> { private long id; private String email; private Date createdOn;
// other getters and setters omitted
public Date getCreatedOn() { return createdOn; }
public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; }
@Override public int compareTo(User u) { if (getCreatedOn() == null || u.getCreatedOn() == null) { return 0; } return getCreatedOn().compareTo(u.getCreatedOn()); } }
Теперь мы можем вызвать Collections.sort () для выполнения сортировки.
Сортировать по дате создания по возрастанию
Collections.sort(users);
Сортировать по дате создания по убыванию
Collections.sort(users);
Collections.reverse(users);
Этот параметр требует изменения нашего класса и определения порядка сортировки по умолчанию (или естественного). Для сортировки в порядке убывания требуется два отдельных вызова методов.
Этот вариант не позволяет выполнять сортировку по другому полю, кроме того, которое мы выбрали.
Вариант 2: Collections.sort () с компаратором
Вместо того, чтобы изменять наш класс, мы можем передать компаратор в Collections.sort (). В приведенных ниже примерах создается компаратор с использованием анонимного класса.
Сортировать по дате создания по возрастанию
Collections.sort(users, new Comparator<User>() {
@Override public int compare(User u1, User u2) {
return u1.getCreatedOn().compareTo(u2.getCreatedOn());
} });
Сортировать по дате создания по убыванию
Мы меняем местами u1 и u2, чтобы поменять местами порядок сортировки.
Collections.sort(users, new Comparator<User>() {
@Override public int compare(User u1, User u2) {
return u2.getCreatedOn().compareTo(u1.getCreatedOn());
} });
Этот параметр позволяет коду вне класса определять критерии и порядок сортировки.
Однако для этого требуется уродливый анонимный класс, который не очень читается.
Вариант 3: сортировка интерфейса списка () [Java 8]
Java 8 представила метод сортировки в интерфейсе List, который может использовать компаратор.
Метод Comparator.comparing () принимает ссылку на метод, которая служит основой для сравнения. Итак, мы передаем User :: getCreatedOn для сортировки по полю createdOn.
Сортировать по дате создания по возрастанию
users.sort(Comparator.comparing(User::getCreatedOn));
Сортировать по дате создания по убыванию
users.sort(Comparator.comparing(User::getCreatedOn).reversed());
Как видим, код становится намного проще и удобнее для чтения.
Вариант 4. Интерфейс потока sorted () [Java 8]
Предположим, мы не хотим изменять исходный список, а возвращаем новый отсортированный список.
В этой ситуации мы можем использовать метод sorted () из интерфейса Stream, представленного в Java 8.
Вернуть новый список, отсортированный по дате создания по возрастанию
List<User> sortedUsers = users.stream()
.sorted(Comparator.comparing(User::getCreatedOn))
.collect(Collectors.toList());
Вернуть новый список, отсортированный по дате создания по убыванию
List<User> sortedUsers = users.stream()
.sorted(Comparator.comparing(User::getCreatedOn).reversed())
.collect(Collectors.toList());
Вывод
Хотя каждый из обсуждаемых параметров выполняет сортировку, рекомендуется использовать последние два параметра, поскольку их легче кодировать, отлаживать и читать.
Первоначально опубликовано на www.codebyamir.com 9 мая 2018 г.