Pages

Footer Pages

Spring Boot

Java String API

Java Conversions

Kotlin Programs

Kotlin Conversions

Java Threads Tutorial

Java 8 Tutorial

Saturday, December 4, 2021

Java 8 Comparator thenComparing()

1. Overview

In this tutorial, We'll learn how to use Comparator.thenComparing() method in java 8 streams.

thenComparing() method is used to sort the list of objects by multiple fields. 


And also thenComparing() method is used to merge or join two comparators as a single one. The merged comparator is used to sort the collection by multiple fields.

Syntax:
default Comparator<T> thenComparing(Comparator<? super T> other)
This method returns a lexicographic-order comparator with another comparator. If this Comparator considers two elements equal, i.e. compare(a, b) == 0, other is used to determine the order.

Java 8 Comparator thenComparing() - Sort By Multiple Fields




2. Java 8 Comparator thenComparing() Example by two fields


Look at the example that sorts the list of objects by two properties.

First, we need to have two Comparator instances created using comparing() method in java 8.

After that we need to call the thenComparing() method on the first comparator and pass the second comparator to thenComparing() method. This method returns the third comparator which is holding two fields from comparator 1 and comparator 2.

For comparing() method we need to pass the lambda expression to the comparator.

Example 1
package com.javaprogramto.java8.comparator.thencomparing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortByTwoFieldsByThenComparing {

	public static void main(String[] args) {

		List<Author> authors = new ArrayList<>();

		authors.add(new Author(100, "Bakliwal", "R", "Shagun", 10));
		authors.add(new Author(101, "Bakliwal", "R", "Baalen", 10));
		authors.add(new Author(101, "Bakliwal", "P", "Bakliwal", 10));
		authors.add(new Author(101, "Ashish", "S", "Paradkar", 10));
		authors.add(new Author(101, "Ashish", "P", "Bakliwal", 10));
		authors.add(new Author(101, "Ashish", "S", "Ameen", 10));

		// first comparator - comparator by lamdba expression
		Comparator<Author> firstNameComparator = (a1, a2) -> a1.getFirstName().compareTo(a2.getFirstName());

		// second comparator - comparing() method by method reference
		Comparator<Author> middleNameComparator = Comparator.comparing(Author::getMiddleName);

		// thenComparing() method to merge 2 comparator
		Comparator<Author> firstMiddleNamesComparator = firstNameComparator.thenComparing(middleNameComparator);

		System.out.println("Before sorting by two fields");
		authors.forEach(a -> System.out.println(a));

		Collections.sort(authors, firstMiddleNamesComparator);

		System.out.println("after sorting merged comparator");
		authors.forEach(a -> System.out.println(a));

	}

}

class Author {
	int id;
	String firstName;
	String middleName;
	String lastName;
	int noOfBooks;

	public Author(int id, String firstName, String middleName, String lastName, int noOfBooks) {
		super();
		this.id = id;
		this.firstName = firstName;
		this.middleName = middleName;
		this.lastName = lastName;
		this.noOfBooks = noOfBooks;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getNoOfBooks() {
		return noOfBooks;
	}

	public void setNoOfBooks(int noOfBooks) {
		this.noOfBooks = noOfBooks;
	}

	@Override
	public String toString() {
		return "Author [id=" + id + ", firstName=" + firstName + ", middleName=" + middleName + ", lastName=" + lastName
				+ ", noOfBooks=" + noOfBooks + "]";
	}

}

Output
Before sorting by two fields
Author [id=100, firstName=Bakliwal, middleName=R, lastName=Shagun, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=R, lastName=Baalen, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Paradkar, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Ameen, noOfBooks=10]

after sorting merged comparator
Author [id=101, firstName=Ashish, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Paradkar, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Ameen, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=100, firstName=Bakliwal, middleName=R, lastName=Shagun, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=R, lastName=Baalen, noOfBooks=10]


3. Java 8 Comparator thenComparing() Example by Three or more fields


In the below program let us sort the first, middle and last names together by 3 fields.

First, create three separate comparators using Comparator.comparing() method by passing method reference.


Next, merge all these three names comparators into a single one by using thenComparing() method chain.

Example 2
package com.javaprogramto.java8.comparator.thencomparing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortByThreeFieldsByThenComparing {

	public static void main(String[] args) {

		List<Author> authors = new ArrayList<>();

		authors.add(new Author(100, "Bakliwal", "R", "Shagun", 10));
		authors.add(new Author(101, "Bakliwal", "R", "Baalen", 10));
		authors.add(new Author(101, "Bakliwal", "P", "Bakliwal", 10));
		authors.add(new Author(101, "Ashish", "S", "Paradkar", 10));
		authors.add(new Author(101, "Ashish", "P", "Bakliwal", 10));
		authors.add(new Author(101, "Ashish", "S", "Ameen", 10));

		// first comparator - comparing() method by method reference
		Comparator<Author> firstNameComparator = Comparator.comparing(Author::getFirstName);

		// second comparator - comparing() method by method reference
		Comparator<Author> middleNameComparator = Comparator.comparing(Author::getMiddleName);

		// second comparator - comparing() method by method reference
		Comparator<Author> lastNameComparator = Comparator.comparing(Author::getLastName);

		// thenComparing() method to merge 3 comparators in chain.
		Comparator<Author> firstMiddleNamesComparator = firstNameComparator.thenComparing(middleNameComparator)
				.thenComparing(lastNameComparator);

		System.out.println("Before sorting by 3 fields");
		authors.forEach(a -> System.out.println(a));

		Collections.sort(authors, firstMiddleNamesComparator);

		System.out.println("after sorting merged comparator");
		authors.forEach(a -> System.out.println(a));
	}
}

Output
Before sorting by 3 fields
Author [id=100, firstName=Bakliwal, middleName=R, lastName=Shagun, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=R, lastName=Baalen, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Paradkar, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Ameen, noOfBooks=10]

after sorting merged comparator
Author [id=101, firstName=Ashish, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Ameen, noOfBooks=10]
Author [id=101, firstName=Ashish, middleName=S, lastName=Paradkar, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=P, lastName=Bakliwal, noOfBooks=10]
Author [id=101, firstName=Bakliwal, middleName=R, lastName=Baalen, noOfBooks=10]
Author [id=100, firstName=Bakliwal, middleName=R, lastName=Shagun, noOfBooks=10]

From the above output, we can see that the last name is sorted properly when the first and middle names are the same. That means merged comparator using thenComparing() method is worked fine.


4. Java 8 Comparator thenComparing() Example 3


We can use list.sort() rathar than using Collections.sort() method.

Example 3
// first comparator - comparing() method by method reference
Comparator<Author> firstNameComparator = Comparator.comparing(Author::getFirstName);

// second comparator - comparing() method by method reference
Comparator<Author> middleNameComparator = Comparator.comparing(Author::getMiddleName);

// second comparator - comparing() method by method reference
Comparator<Author> lastNameComparator = Comparator.comparing(Author::getLastName);

// thenComparing() method to merge 3 comparators in chain.
Comparator<Author> fullNamesComparator = firstNameComparator.thenComparing(middleNameComparator)
.thenComparing(lastNameComparator);

authors.sort(fullNamesComparator);


This list.sort() method also produces the same output as in the above section.


5. Conclusion


In this article, We've seen how to use Comparator.thenComparing() method to sort the list of custom objects by multiple fields.

Comparator interface has a different sets of methods thenComparingDouble(), thenComparingInt() and thenComparingLong() for primitive int, double and long fields.




No comments:

Post a Comment

Please do not add any spam links in the comments section.