Java Comparator thenComparing() Example

Java 8 example of sorting a collection of objects on multiple fields (ORDER BY sort) using Comparator thenComparing() method.

Java 10

Java example of sorting a List of objects by multiple fields using Comparator.thenComparing() method. This method returns a lexicographic-order Comparator with another specified Comparator. This method gives the same effect as SQL ORDER BY clause.

//first name comparator
Comparator<Employee> compareByFirstName = Comparator.comparing( Employee::getFirstName );
 
//last name comparator
Comparator<Employee> compareByLastName = Comparator.comparing( Employee::getLastName );
 
//Compare by first name and then last name (multiple fields)
Comparator<Employee> compareByFullName = compareByFirstName.thenComparing(compareByLastName);
 
//Use Comparator
Collections.sort(employees, compareByFullName);

Sorting on Multiple Fields – ORDER BY Sort

Example of using thenComparing() to create Comparator which is capable of sorting by multiple fields.

private static ArrayList<Employee> getUnsortedEmployeeList() 
{
	ArrayList<Employee> list = new ArrayList<>();
	list.add( new Employee(2, "Lokesh", "Gupta") );
	list.add( new Employee(1, "Alex", "Gussin") );
	list.add( new Employee(4, "Brian", "Sux") );
	list.add( new Employee(5, "Neon", "Piper") );
	list.add( new Employee(3, "David", "Beckham") );
	list.add( new Employee(7, "Alex", "Beckham") );
	list.add( new Employee(6, "Brian", "Suxena") );
  return list;
}


ArrayList<Employee> employees = getUnsortedEmployeeList();
 
//Compare by first name and then last name
Comparator<Employee> compareByName = Comparator
                    .comparing(Employee::getFirstName)
                    .thenComparing(Employee::getLastName);
 
Collections.sort(employees, compareByName);

Checkout the program output that has the employees sorted first by firstName, and then by lastName in dictionary order.

[E[id=7, firstName=Alex,  lastName=Beckham], 
E [id=1, firstName=Alex,  lastName=Gussin], 
E [id=4, firstName=Brian,   lastName=Sux], 
E [id=6, firstName=Brian,   lastName=Suxena], 
E [id=3, firstName=David,   lastName=Beckham], 
E [id=2, firstName=Lokesh,  lastName=Gupta], 
E [id=5, firstName=Neon,  lastName=Piper]]

Drop me your questions in the comments section.

Happy Learning !!

Leave a Comment

  1. how can you write above example using lambda experession.
    i.e how to write these method reference into lambda expression ?

    .comparing(Employee::getFirstName)
                        .thenComparing(Employee::getLastName);
    
    Reply
      • thanks Lokesh for your reply.
        Actually, Lambda exp. and Method Reference are inter changeable. We use method reference where we can use Lambda exp. and its good way to do java programming but I’m not very comfortable in Method Ref so i always use Lambda first and then convert in method reference for my self understanding. thats the only reason.

        Reply
  2. We have a data structure where some of the field values are null, so we are getting NullPointer exception, how to handle that?

    Exception in thread "main" java.lang.NullPointerException
    	at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
    	at java.base/java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:217)
    	at java.base/java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:216)
    	at java.base/java.util.Comparator.lambda$thenComparing$36697e65$1(Comparator.java:216)
    	at java.base/java.util.TimSort.binarySort(TimSort.java:296)
    	at java.base/java.util.TimSort.sort(TimSort.java:221)
    	at java.base/java.util.Arrays.sort(Arrays.java:1515)
    	at java.base/java.util.ArrayList.sort(ArrayList.java:1749)
    	at java.base/java.util.Collections.sort(Collections.java:177)
    Reply
  3. Player class constructor :

    public Player (	String playerName, 
    		Integer matchesPlayed, 
    		Integer runs, 
    		Integer highestScore, 
    		Country country) 
    {
    	super();
    	this.playerName = playerName;
    	this.matchesPlayed = matchesPlayed;
    	this.runs = runs;
    	this.highestScore = highestScore;
    	this.country = country;
    }
    
    public static List players = Arrays.asList(
    	new Player("Virat", 52, 5200, 100, new Country(1, "India")),
    	new Player("Williamson", 4200, 550, 90, new Country(2, "New Zealand")),
    	new Player("Smith", 262, 6500, 35, new Country(3, "Australia")),
    	new Player("Chris", 321, 7000, 150, new Country(4, "West Indies")),
    	new Player("Gayle", 250, 3200, 45, new Country(4, "West Indies")),
    	new Player("MS Dhoni", 102, 5020, 109, new Country(5, "India"))
    );

    Suppose I have a above list. Player and country has a relationship.

    How can I sort the list by country name and then by matches Played in reversed order.

    Reply
    • Suppose I have.

      public Country (Integer id, String countryName)

      Comparator compareByCountryAndPlayer = Comparator
              .comparing(p -> p.getCountry().getCountryName())
              .thenComparing(Player::getMatchesPlayed, Comparator.reverseOrder());
      Reply
  4. Nice tutorial but I am stuck with another problem.How to sort a list of object based on two field where we have to sort one field in ascending order and one field in descending order?

    Reply

Leave a Comment

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.