Sort a List of Objects by Field in Java

Overview

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


List of Objects

We'll use the following User class in our examples:
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:

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

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

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.

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.