$show=/label

Java Comparator

SHARE:

A quick guide to Comparator interface in java for custom sorting for the collections.

1. Overview

In this tutorial, We'll learn how to use the Comparator interface in java.

A comparator interface is used to order the user-defined object in sorted order. This comparator interface has the capability to compare the same type of objects.

Comparator is used to sort the object in ascending or descending order.

We will write the example programs on custom objects with a single field or property.
And also how to sort the collection such as a list or set by multiple properties.

Java Comparator




2. Comparator Interface


The comparator interface is enriched with new methods in java 8. But before java 8, Comparator has only two methods abstract methods those are compare() and equals() methods.

Syntax
int compare(T o1, T o2)
boolean	equals(Object obj)


3. Comparator Methods


Below are the methods that are added in JDK 1.8 and above. Some of them are static and default.

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
Accepts a function that extracts a Comparable sort key from a type T, and returns a Comparator<T> that compares by that sort key.

static <T,U> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator)
Accepts a function that extracts a sort key from a type T, and returns a Comparator<T> that compares by that sort key using the specified Comparator.

static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor)
Accepts a function that extracts a double sort key from a type T, and returns a Comparator<T> that compares by that sort key.

static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor)
Accepts a function that extracts an int sort key from a type T, and returns a Comparator<T> that compares by that sort key.

static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)
Accepts a function that extracts a long sort key from a type T, and returns a Comparator<T> that compares by that sort key.

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
Returns a comparator that compares Comparable objects in natural order.

static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
Returns a null-friendly comparator that considers null to be less than non-null.

static <T> Comparator<T> nullsLast(Comparator<? super T> comparator)
Returns a null-friendly comparator that considers null to be greater than non-null.

default Comparator<T> reversed()
Returns a comparator that imposes the reverse ordering of this comparator.

static <T extends Comparable<? super T>> Comparator<T> reverseOrder()
Returns a comparator that imposes the reverse of the natural ordering.

default Comparator<T> thenComparing(Comparator<? super T> other)
Returns a lexicographic-order comparator with another comparator.

default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor)
Returns a lexicographic-order comparator with a function that extracts a Comparable sort key.

default <U> Comparator<T> thenComparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator)
Returns a lexicographic-order comparator with a function that extracts a key to be compared with the given Comparator.

default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor)
Returns a lexicographic-order comparator with a function that extracts a double sort key.

default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor)
Returns a lexicographic-order comparator with a function that extracts a int sort key.

default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor)
Returns a lexicographic-order comparator with a function that extracts a long sort key.


4. Compartor Sorting With Single Property or Field


Let us create the custom class Teacher with the properties name, subject, experience. Add the teacher objects to the List. Now we want to sort the list by teacher name.

This can be solved in two ways.

A) By writing our own custom sorting logic to sort it by teacher name.
B) By using comparator interface: This interface is having the compare() method. This is used to order the same type of objects by a specific field. In our case, it is by teacher name.

Next, we need to pass the custom comparator to the Collections.sort() method as below.
Collections.sort(list, customComparator);

How does Collections.sort() method work in java?

Internally, Collections.sort() method calls compare() method of custom comparator class. This compare() method logic gets executed. This method returns integer values such as positive or negative or zero. The returned value is used to swap the objects.

Let us write the full comparator example code to sort by one field.

The below example sorts the list of teacher objects by the subject they teach.

Example 
package com.javaprogramto.java8.comparator;

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

public class ComparatorExample {

	public static void main(String[] args) {

		List<Teacher> teachers = new ArrayList<>();

		teachers.add(new Teacher("Rajesh", "Science", 10));
		teachers.add(new Teacher("Mahesh", "Mathematics", 5));
		teachers.add(new Teacher("Suresh", "English", 10));
		teachers.add(new Teacher("Rakesh", "Science", 3));
		teachers.add(new Teacher("Ramesh", "Mathematics", 8));

		System.out.println("Teachers object before sorting");
		teachers.forEach(teacher -> System.out.println("Teacher name - " + teacher.getName() + ", subject - "
				+ teacher.getSubject() + ", exp - " + teacher.getExperience()));

		Collections.sort(teachers, new SubjectComparator());

		System.out.println("\nTeachers object after sorting");
		teachers.forEach(teacher -> System.out.println("Teacher name - " + teacher.getName() + ", subject - "
				+ teacher.getSubject() + ", exp - " + teacher.getExperience()));

	}

}

// Custom comparator to sort Teacher objects by subject they teach
class SubjectComparator implements Comparator<Teacher> {

	@Override
	public int compare(Teacher t1, Teacher t2) {

		return t1.getSubject().compareTo(t2.getSubject());
	}

}

class Teacher {

	String name;
	String subject;
	int experience;

	public Teacher(String name, String subject, int experience) {
		super();
		this.name = name;
		this.subject = subject;
		this.experience = experience;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public int getExperience() {
		return experience;
	}

	public void setExperience(int experience) {
		this.experience = experience;
	}
}

Output
Teachers object before sorting
Teacher name - Rajesh, subject - Science, exp - 10
Teacher name - Mahesh, subject - Mathematics, exp - 5
Teacher name - Suresh, subject - English, exp - 10
Teacher name - Rakesh, subject - Science, exp - 3
Teacher name - Ramesh, subject - Mathematics, exp - 8

Teachers object before sorting
Teacher name - Suresh, subject - English, exp - 10
Teacher name - Mahesh, subject - Mathematics, exp - 5
Teacher name - Ramesh, subject - Mathematics, exp - 8
Teacher name - Rajesh, subject - Science, exp - 10
Teacher name - Rakesh, subject - Science, exp - 3

4. Compartor Sorting With more than one field


As of now, we have seen the custom sorting based on the one field of teacher class. 

The above section output is sorted by the natural order of the subject field and you could see the same subject is taught by two teachers. But those teachers differ in their experience. In such cases, we may not get the teachers objects in the proper order. 

The actual order is sorted by subject and their experience in ascending order. 

To get this output, we need to another field to the existing sorting logic within the custom comparator.

Look at the below comparator with multiple fields for sorting on subject and experience fields.

Example program to sort by multiple fields with a comparator interface
package com.javaprogramto.java8.comparator;

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

public class ComparatorExample2 {

	public static void main(String[] args) {

		List<Teacher> teachers = new ArrayList<>();

		teachers.add(new Teacher("Rajesh", "Science", 10));
		teachers.add(new Teacher("Mahesh", "Mathematics", 5));
		teachers.add(new Teacher("Suresh", "English", 10));
		teachers.add(new Teacher("Rakesh", "Science", 3));
		teachers.add(new Teacher("Ramesh", "Mathematics", 8));

		System.out.println("Teachers object before sorting");
		teachers.forEach(teacher -> System.out.println("Teacher name - " + teacher.getName() + ", subject - "
				+ teacher.getSubject() + ", exp - " + teacher.getExperience()));

		Collections.sort(teachers, new SubjectExperienceComparator());

		System.out.println("\nTeachers object before sorting");
		teachers.forEach(teacher -> System.out.println("Teacher name - " + teacher.getName() + ", subject - "
				+ teacher.getSubject() + ", exp - " + teacher.getExperience()));

	}

}

// Custom comparator to sort Teacher objects by subject they teach and their experience level
class SubjectExperienceComparator implements Comparator<Teacher> {

	@Override
	public int compare(Teacher t1, Teacher t2) {

		int name = t1.getSubject().compareTo(t2.getSubject());

		int exp = Integer.valueOf(t1.getExperience()).compareTo(t2.getExperience());

		return name == 0 ? exp : name;
	}

}


Output
Teachers object before sorting
Teacher name - Rajesh, subject - Science, exp - 10
Teacher name - Mahesh, subject - Mathematics, exp - 5
Teacher name - Suresh, subject - English, exp - 10
Teacher name - Rakesh, subject - Science, exp - 3
Teacher name - Ramesh, subject - Mathematics, exp - 8

Teachers object before sorting
Teacher name - Suresh, subject - English, exp - 10
Teacher name - Mahesh, subject - Mathematics, exp - 5
Teacher name - Ramesh, subject - Mathematics, exp - 8
Teacher name - Rakesh, subject - Science, exp - 3
Teacher name - Rajesh, subject - Science, exp - 10

5. Java 8 - Comparator sorting by a single field


In java 8, a Comparator can be created with the help of lambda expressions.

5.1 Using Collections.sort()


In the below example, SubjectCompartor is created by using a lambda statement. This can be passed to the Collections.sort() method.

Example 
Comparator<Teacher> subjectComparator = (t1, t2) -> t1.getSubject().compareTo(t2.getSubject());
		
Collections.sort(teachers, subjectComparator);


5.2 Using Comparator.comparing()


Comparator interface has comparing() method which is a static method. comparing() method is used to create the custom comparator and can be passed to the Collections.sort() method.

We have passed the method reference to the comparing() method.

Example
Comparator<Teacher> subjectComparator = Comparator.comparing(Teacher::getSubject);

Collections.sort(teachers, subjectComparator);


5.3 Using Stream.sort()


Java 8 Stream API has sort() method which takes the custom comparator for soring the stream of objects.

Create the comparator with lambda or method ref and then pass it to the sorted() method of the stream.

Example
Comparator<Teacher> subjectComparator1 = Comparator.comparing(Teacher::getSubject);

List<Teacher> sortedList1 = teachers.stream().sorted(subjectComparator1).collect(Collectors.toList());

Comparator<Teacher> subjectComparator2 = (t1, t2) -> t1.getSubject().compareTo(t2.getSubject());

List<Teacher> sortedList2 = teachers.stream().sorted(subjectComparator2).collect(Collectors.toList());


6. Java 8 - Comparator sorting by multiple fields


More than one field-based sorting can be easily done by using java 8 concepts.

We can use a custom comparator created by any way that can be used with the stream.sorted() or Collections.sort() method.


To add sort by multiple properties with Collections.comparing() method, you need to use thenComparing() method to add additional fields to Comparator. Like this, you can call thenComparint() method multiple times on base comparor as chain.

Look at the below example that covers all possible combinations.


Example 
// using streams.sort


// way 1 - comparator with method ref and comparing() and thenComparing() method.
Comparator<Teacher> subjectExpComparator1 = Comparator.comparing(Teacher::getSubject)
		.thenComparing(Teacher::getExperience);

List<Teacher> sortedList1 = teachers.stream().sorted(subjectExpComparator1).collect(Collectors.toList());

// way 2 - lambda with comparator 
Comparator<Teacher> subjectExpComparator2 = (t1, t2) -> {

	int subjectCompare = t1.getSubject().compareTo(t2.getSubject());
	int expCompare = Integer.valueOf(t1.getExperience()).compareTo(t2.getExperience());
	return subjectCompare == 0 ? expCompare : subjectCompare;
};

List<Teacher> sortedList2 = teachers.stream().sorted(subjectExpComparator1).collect(Collectors.toList());

// way 3 - with anonymous comparator
Comparator<Teacher> subjectExpComparator3 = new Comparator<Teacher>() {

	@Override
	public int compare(Teacher o1, Teacher o2) {
		int subjectCompare = t1.getSubject().compareTo(t2.getSubject());
		int expCompare = Integer.valueOf(t1.getExperience()).compareTo(t2.getExperience());
		return subjectCompare == 0 ? expCompare : subjectCompare;
	}
};

List<Teacher> sortedList3 = teachers.stream().sorted(subjectExpComparator3).collect(Collectors.toList());

// using collections.sort

Collections.sort(teachers, subjectExpComparator1);
Collections.sort(teachers, subjectExpComparator2);
Collections.sort(teachers, subjectExpComparator3);

All examples shown in java 8 produce the same output as with before java 8 versions.


7. Conclusion


In this article, We've seen an in-depth comparator interface in java and java 8 methods.

We've seen examples to sort the custom objects by single field and two or more fields with a comparator with java 8 streams.




COMMENTS

BLOGGER

About Us

Author: Venkatesh - I love to learn and share the technical stuff.
Name

accumulo,1,ActiveMQ,2,Adsense,1,API,37,ArrayList,18,Arrays,24,Bean Creation,3,Bean Scopes,1,BiConsumer,1,Blogger Tips,1,Books,1,C Programming,1,Collection,8,Collections,37,Collector,1,Command Line,1,Comparator,1,Compile Errors,1,Configurations,7,Constants,1,Control Statements,8,Conversions,6,Core Java,149,Corona India,1,Create,2,CSS,1,Date,3,Date Time API,38,Dictionary,1,Difference,2,Download,1,Eclipse,3,Efficiently,1,Error,1,Errors,1,Exceptions,8,Fast,1,Files,17,Float,1,Font,1,Form,1,Freshers,1,Function,3,Functional Interface,2,Garbage Collector,1,Generics,4,Git,9,Grant,1,Grep,1,HashMap,2,HomeBrew,2,HTML,2,HttpClient,2,Immutable,1,Installation,1,Interview Questions,6,Iterate,2,Jackson API,3,Java,32,Java 10,1,Java 11,6,Java 12,5,Java 13,2,Java 14,2,Java 8,128,Java 8 Difference,2,Java 8 Stream Conversions,4,java 8 Stream Examples,12,Java 9,1,Java Conversions,14,Java Design Patterns,1,Java Files,1,Java Program,3,Java Programs,114,Java Spark,1,java.lang,4,java.util. function,1,JavaScript,1,jQuery,1,Kotlin,11,Kotlin Conversions,6,Kotlin Programs,10,Lambda,2,lang,29,Leap Year,1,live updates,1,LocalDate,1,Logging,1,Mac OS,3,Math,1,Matrix,6,Maven,1,Method References,1,Mockito,1,MongoDB,3,New Features,1,Operations,1,Optional,6,Oracle,5,Oracle 18C,1,Partition,1,Patterns,1,Programs,1,Property,1,Python,2,Quarkus,1,Read,1,Real Time,1,Recursion,2,Remove,2,Rest API,1,Schedules,1,Serialization,1,Servlet,2,Sort,1,Sorting Techniques,8,Spring,2,Spring Boot,23,Spring Email,1,Spring MVC,1,Streams,31,String,61,String Programs,28,String Revese,1,StringBuilder,1,Swing,1,System,1,Tags,1,Threads,11,Tomcat,1,Tomcat 8,1,Troubleshoot,26,Unix,3,Updates,3,util,5,While Loop,1,
ltr
item
JavaProgramTo.com: Java Comparator
Java Comparator
A quick guide to Comparator interface in java for custom sorting for the collections.
https://blogger.googleusercontent.com/img/a/AVvXsEiZcwginll1AOkcyQQlAYdadSS-W9gyAW-zuvgVqZWXvNUdnYE2APCAl9Zji6gtTXoqROvkUk7E4EEICmWGnRacpi7FGXe82XAGlolZ10dnsJfl3PdRneMWKDr35xvpRZpVakeVsIJ5RoXH7oBbRZZfkB3NgqH4Z3oFhMGEV8iZiVaCaZkSQFTQpbbl=w400-h221
https://blogger.googleusercontent.com/img/a/AVvXsEiZcwginll1AOkcyQQlAYdadSS-W9gyAW-zuvgVqZWXvNUdnYE2APCAl9Zji6gtTXoqROvkUk7E4EEICmWGnRacpi7FGXe82XAGlolZ10dnsJfl3PdRneMWKDr35xvpRZpVakeVsIJ5RoXH7oBbRZZfkB3NgqH4Z3oFhMGEV8iZiVaCaZkSQFTQpbbl=s72-w400-c-h221
JavaProgramTo.com
https://www.javaprogramto.com/2021/12/java-comparator.html
https://www.javaprogramto.com/
https://www.javaprogramto.com/
https://www.javaprogramto.com/2021/12/java-comparator.html
true
3124782013468838591
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content