Java Comparator.thenComparing

By Arvind Rai, March 15, 2019
thenComparing is the default method of Comparator functional interface. Comparator.thenComparing method is introduced in Java 8. Comparator.thenComparing returns a lexicographic-order comparator that is called by a Comparator instance to sort the items using group of sort keys. When this comparator compares two elements equal then thenComparing method determines the order. We can use Comparator.thenComparing multiple times. It is useful when we want to determine the order of elements by the group of sort keys. For the int, long and double datatype sort keys, Comparator has thenComparingInt, thenComparingLong and thenComparingDouble default methods respectively.

Comparator.thenComparing

thenComparing has following forms.
1.
default Comparator<T> thenComparing(Comparator<? super T> other) 
It returns a lexicographic-order comparator with another comparator. Find the code snippet.
Comparator<Student> compByStdName = Comparator.comparing(Student::getName);
Comparator<Student> schoolComparator1 = Comparator.comparing(Student::getAge) //sort by student age
	.thenComparing(compByStdName); //then sort by student name 
First the comparator will sort the collections of Student by student age and if for some student, there are equal age then it will be sorted by their name.
2.
default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor) 
It returns a lexicographic-order comparator with a function that extracts a Comparable sort key. Find the code snippet.
Comparator<Student> schoolComparator2 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
	.thenComparing(Student::getAge) //then sort by student age
	.thenComparing(Student::getName); //then sort by student name 
First the collections of Student will be sorted by their respective School with its natural order and if some students are equal according to their School ordering then those students will be sorted by their respective age and if ages are also equals then they will be sorted by their name.
3.
default <U> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator) 
It returns a lexicographic-order comparator with a function that extracts a key to be compared with the given Comparator. Find the code snippet.
Comparator<Student> schoolComparator3 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
	.thenComparing(Student::getSchool, (school1, school2) -> school1.getSname().compareTo(school2.getSname())) //then sort by school name 
	.thenComparing(Student::getAge) //then sort by student age
	.thenComparing(Student::getName); //then sort by student name 
First the collections of Student will be sorted by their respective School with its natural order (i.e. by school city in our demo) then if the students are with same school city, they will be sorted by their respective school name and if the students are with same school name, they will be sorted by their age and if the students are with same age, they will be sorted by their name.

Now find the complete example.
School.java
package com.concretepage;
public class School implements Comparable<School> {
  private String sname;
  private String city;  
  public School(String sname, String city) {
	this.sname = sname;
	this.city = city;
  }
  public String getSname() {
        return sname;
  }
  public String getCity() {
        return city;
  }
  @Override
  public int compareTo(School s) {
	return s.getCity().compareTo(city);
  }
} 
Student.java
package com.concretepage;
import java.util.Arrays;
import java.util.List;
public class Student {
  private String name;
  private int age;
  private long homeDistance;
  private double weight;
  private School school;

  public Student(String name, int age, long homeDistance, double weight, School school) {
	this.name = name;
	this.age = age;
	this.homeDistance = homeDistance;
	this.weight = weight;
	this.school = school;
  }
  public String getName() {
	return name;
  }
  public int getAge() {
	return age;
  }
  public long getHomeDistance() {
	return homeDistance;
  }
  public double getWeight() {
	return weight;
  }
  public School getSchool() {
	return school;
  }
  public static List<Student> getStudentList() {
	Student s1 = new Student("Ram", 18, 3455, 60.75, new School("AB College", "Noida"));
	Student s2 = new Student("Shyam", 22, 3252, 65.80, new School("RS College", "Gurugram"));
	Student s3 = new Student("Mohan", 18, 1459, 65.20, new School("AB College", "Noida"));
	Student s4 = new Student("Mahesh", 22, 4450, 70.25, new School("RS College", "Gurugram"));
	List<Student> list = Arrays.asList(s1, s2, s3, s4);
	return list;
  }
} 
ThenComparingDemo.java
package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();
    
    System.out.println("--------Example-1---------"); 
    
    Comparator<Student> compByStdName = Comparator.comparing(Student::getName);
    Comparator<Student> schoolComparator1 = Comparator.comparing(Student::getAge) //sort by student age
    	.thenComparing(compByStdName); //then sort by student name   
    
    Collections.sort(list, schoolComparator1);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));
    
    System.out.println("--------Example-2---------");   
    
    Comparator<Student> schoolComparator2 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
    	.thenComparing(Student::getAge) //then sort by student age
    	.thenComparing(Student::getName); //then sort by student name   
    
    Collections.sort(list, schoolComparator2);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getCity()));
    
    System.out.println("--------Example-3---------");    
    
    Comparator<Student> schoolComparator3 = Comparator.comparing(Student::getSchool) //sort by school natural ordering i.e. city
    	.thenComparing(Student::getSchool, (school1, school2) -> school1.getSname().compareTo(school2.getSname())) //then sort by school name 
    	.thenComparing(Student::getAge) //then sort by student age
    	.thenComparing(Student::getName); //then sort by student name 
    
    Collections.sort(list, schoolComparator3);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()+ "-" + s.getSchool().getSname() + "-" + s.getSchool().getCity()));
  }
} 
Output
--------Example-1---------
Mohan-18
Ram-18
Mahesh-22
Shyam-22
--------Example-2---------
Mohan-18-Noida
Ram-18-Noida
Mahesh-22-Gurugram
Shyam-22-Gurugram
--------Example-3---------
Mohan-18-AB College-Noida
Ram-18-AB College-Noida
Mahesh-22-RS College-Gurugram
Shyam-22-RS College-Gurugram 

Comparator.thenComparingInt

Find the thenComparingInt method declaration.
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) 
It returns a lexicographic-order comparator with a function that extracts an int sort key. Find the example.
ThenComparingIntDemo.java
package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingIntDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();
    
    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
    	.thenComparingInt(Student::getAge);
    
    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getAge()));    
  }
} 
Output
Mohan-18
Mahesh-22
Ram-18
Shyam-22 

Comparator.thenComparingLong

Find the thenComparingLong method declaration.
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) 
It returns a lexicographic-order comparator with a function that extracts a long sort key. Find the example.
ThenComparingLongDemo.java
package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingLongDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();
    
    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
    	.thenComparingLong(Student::getHomeDistance);
    
    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getHomeDistance()));  
  }
} 
Output
Mohan-1459
Mahesh-4450
Ram-3455
Shyam-3252 

Comparator.thenComparingDouble

Find the thenComparingDouble method declaration.
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) 
It returns a lexicographic-order comparator with a function that extracts a double sort key. Find the example.
ThenComparingDoubleDemo.java
package com.concretepage;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ThenComparingDoubleDemo {
  public static void main(String[] args) {
    List<Student> list = Student.getStudentList();
    
    Comparator<Student> comparator = Comparator.comparing(Student::getName, (s1, s2) -> s1.charAt(0) - s2.charAt(0))
    	.thenComparingDouble(Student::getWeight);
    
    Collections.sort(list, comparator);
    list.forEach(s->System.out.println(s.getName() + "-" + s.getWeight()));         
  }
} 
Output
Mohan-65.2
Mahesh-70.25
Ram-60.75
Shyam-65.8 

References

Interface Comparator
Java Comparator.comparing
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us