Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to sort a list of objects by a field

Short answer

Pass sort() a comparator created by Comparator.comparing() for the field you need:

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

Output:

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

Descending order

reversed() flips the comparator's order:

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

Output:

Boris 41
Anna 30
Oleg 25

By a string field

Strings are compared alphabetically. For number fields comparingInt() is better — it does not box the numbers:

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

Output:

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

Without changing the list

sort() changes the list itself. A stream with sorted() returns a new one:

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

Output:

Anna
Oleg

Common mistake

Sorting a list made with List.of(). It is unmodifiable, so sort() throws:

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

Output:

Exception in thread "main" java.lang.UnsupportedOperationException

Copy it into new ArrayList<>(...) first or use stream().sorted().

Functions used in this recipe

Thanks for reading!

Donate to the site — we work hard for you.