Skip to main content
  1. blog/

Sort a List of Objects by Field in Java

·3 mins

Note

This article was written over 5 years ago. Some information may be outdated or irrelevant.

Overview #

Java provides a number of ways to sort a list.   In this article, I’ll demonstrate how to sort a list of objects by field.


List of Objects #

We’ll use the following User class in our examples:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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;
  }
}

Suppose we have a service method that returns a list of all users:

List<User> users = userService.getAllUsers();

Sort a List of Objects by Field #

So we have a list of users and want to sort them by createdDate. 

Let’s cover several different approaches and explore the benefits and limitations of each. 

Option 1: Collections.sort() with Comparable #

We can use the Comparable interface to define the default sort criteria for a class.   

This requires implementing the compareTo() method as seen on lines 20-26 below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.demo;

import java.util.Date;

public class User implements Comparable&lt;User&gt; {
  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());
  }
}

Now we can call Collections.sort() to perform the sort.

Sort by created date ascending #

Collections.sort(users);

Sort by created date descending #

Collections.sort(users);
Collections.reverse(users);

This option requires modifying our class and defining a default (or natural) sort order. Sorting in descending order requires two separate method calls.

This option doesn’t allow for sorting on a different field other than the one we chose.

Option 2: Collections.sort() with Comparator #

Instead of modifying our class, we can pass in a comparator to Collections.sort(). The examples below create a comparator using an anonymous class.

Sort by created date ascending #

1
2
3
4
5
6
Collections.sort(users, new Comparator<User>() {
  @Override
  public int compare(User u1, User u2) {
    return u1.getCreatedOn().compareTo(u2.getCreatedOn());
  }
});

Sort by created date descending #

We swap the order of u1 and u2 to reverse the sort order.

1
2
3
4
5
6
Collections.sort(users, new Comparator<User>() {
  @Override
  public int compare(User u1, User u2) {
    return u2.getCreatedOn().compareTo(u1.getCreatedOn());
  }
});

This option allows code outside the class to dictate the sort criteria and order.

However, it requires an ugly anonymous class that isn’t very readable.

Option 3: List interface sort() [Java 8] #

Java 8 introduced a sort method in the List interface which can use a comparator.

The Comparator.comparing() method accepts a method reference which serves as the basis of the comparison. So we pass User::getCreatedOn to sort by the createdOn field.

Sort by created date ascending #

users.sort(Comparator.comparing(User::getCreatedOn));

Sort by created date descending #

users.sort(Comparator.comparing(User::getCreatedOn).reversed());

As we can see, the code becomes much simpler and easier to read.

Option 4: Stream interface sorted() [Java 8] #

Suppose we didn’t want to modify the original list, but return a new sorted list.

In this situation, we can use the sorted() method from the Stream interface introduced in Java 8.

Return new list sorted by created date ascending #

List<User> sortedUsers = users.stream()
  .sorted(Comparator.comparing(User::getCreatedOn))
  .collect(Collectors.toList());

Return new list sorted by created date descending #

List<User> sortedUsers = users.stream()
  .sorted(Comparator.comparing(User::getCreatedOn).reversed())
  .collect(Collectors.toList());

Conclusion #

While each of the options discussed performs the sorting, the last two options are recommended because they are easier to code, debug, and read.