Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как отсортировать список объектов по полю

Короткий ответ

Передайте в sort() компаратор, созданный Comparator.comparing() по нужному полю:

record User(String name, int age) {}
 
void main() {
    var users = new ArrayList<>(List.of(
            new User("Anna", 30),
            new User("Oleg", 25),
            new User("Boris", 41)));
 
    users.sort(Comparator.comparing(User::age));
    IO.println(users);
}

Результат:

[User[name=Oleg, age=25], User[name=Anna, age=30], User[name=Boris, age=41]]

По убыванию

reversed() разворачивает порядок компаратора:

record User(String name, int age) {}
 
void main() {
    var users = new ArrayList<>(List.of(new User("Anna", 30), new User("Oleg", 25), new User("Boris", 41)));
 
    users.sort(Comparator.comparing(User::age).reversed());
    users.forEach(user -> IO.println(user.name() + " " + user.age()));
}

Результат:

Boris 41
Anna 30
Oleg 25

По строковому полю

Строки сравниваются по алфавиту. Для числовых полей лучше comparingInt() — он не упаковывает числа в объекты:

record Product(String title, int stock) {}
 
void main() {
    var products = new ArrayList<>(List.of(new Product("tea", 2), new Product("coffee", 5)));
 
    products.sort(Comparator.comparing(Product::title));
    IO.println(products);
 
    products.sort(Comparator.comparingInt(Product::stock));
    IO.println(products);
}

Результат:

[Product[title=coffee, stock=5], Product[title=tea, stock=2]]
[Product[title=tea, stock=2], Product[title=coffee, stock=5]]

Без изменения списка

sort() меняет сам список. Поток со sorted() возвращает новый:

record User(String name, int age) {}
 
void main() {
    var users = List.of(new User("Anna", 30), new User("Oleg", 25));
    var byAge = users.stream().sorted(Comparator.comparing(User::age)).toList();
 
    IO.println(users.getFirst().name());
    IO.println(byAge.getFirst().name());
}

Результат:

Anna
Oleg

Частая ошибка

Сортировать список из List.of(). Он неизменяемый, поэтому sort() выбрасывает исключение:

void main() {
    var names = List.of("Oleg", "Anna");
    names.sort(Comparator.naturalOrder());
}

Результат:

Exception in thread "main" java.lang.UnsupportedOperationException

Сначала скопируйте его в new ArrayList<>(...) или используйте stream().sorted().

Функции из этого ответа

  • Comparator.comparing() — Создаёт компаратор, который сравнивает объекты по одному полю.
  • List.sort() — Сортирует список на месте по заданному правилу.
  • Comparator.thenComparing() — Добавляет второй критерий сортировки — для объектов, равных по первому.
  • Comparator.reversed() — Возвращает компаратор с обратным порядком. Для естественного порядка есть Comparator.reverseOrder().

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.