Java Comparator (With Examples)

The Java Comparator interface serves the purpose of arranging the instances of a custom-defined class.

The interface can be located within the java.util package. It is equipped with two methods: compare(Object obj1, Object obj2) and equals(Object element).

The feature allows for various sorting orders, enabling sorting of elements based on different data attributes such as roll number, name, age, or any other criteria.

Methods of Java Comparator Interface

Method Description
public int compare(Object obj1, Object obj2) It compares the first object with the second object.
public boolean equals(Object obj) It is used to compare the current object with the specified object.
public boolean equals(Object obj) It is used to compare the current object with the specified object.

Collections class

The Collections class offers static functions for arranging the items within a collection. In cases where the elements in the collection belong to a Set or Map, the TreeSet or TreeMap can be utilized. Nevertheless, List elements cannot be sorted directly. The Collections class includes functions specifically designed for sorting List elements as well.

Method of Collections class for sorting List elements

The method sort(List list, Comparator c) is utilized to arrange the elements within a List based on the provided Comparator.

Java Comparator Example (Non-generic Old Style)

Let's see the example of sorting the elements of List on the basis of age and name. In this example, we have created 4 java classes:

  • Student.java
  • AgeComparator.java
  • NameComparator.java
  • Simple.java

Student.java

Within this class, there are three attributes: rollno, name, and age, along with a constructor that accepts parameters.

Example

class Student{
int rollno;
String name;
int age;
Student(int rollno,String name,int age){
this.rollno=rollno;
this.name=name;
this.age=age;
}
}

AgeComparator.java

The following class establishes comparison rules according to the age of objects. When the age of the first object surpasses the age of the second object, a positive value is returned, which could be any number like 1, 2, or 10. Conversely, if the age of the first object is lower than the age of the second object, a negative value is returned, which may vary. Finally, when the ages of both objects are the same, the comparison returns a value of 0.

Example

import java.util.*;
class AgeComparator implements Comparator{
public int compare(Object o1,Object o2){
Student s1=(Student)o1;
Student s2=(Student)o2;

if(s1.age==s2.age)
return 0;
else if(s1.age>s2.age)
return 1;
else
return -1;
}
}

NameComparator.java

The provided class offers comparison functionality that relies on the name. In this scenario, the comparison is facilitated through the utilization of the compareTo method from the String class, which inherently handles the comparison process.

Example

import java.util.*;
class NameComparator implements Comparator{
public int compare(Object o1,Object o2){
Student s1=(Student)o1;
Student s2=(Student)o2;

return s1.name.compareTo(s2.name);
}
}

Simple.java

Within this class, we are displaying the object values after arranging them by name and age.

Example

import java.util.*;
import java.io.*;

class Simple{
public static void main(String args[]){

ArrayList al=new ArrayList();
al.add(new Student(101,"Vijay",23));
al.add(new Student(106,"Ajay",27));
al.add(new Student(105,"Jai",21));

System.out.println("Sorting by Name");

Collections.sort(al,new NameComparator());
Iterator itr=al.iterator();
while(itr.hasNext()){
Student st=(Student)itr.next();
System.out.println(st.rollno+" "+st.name+" "+st.age);
}

System.out.println("Sorting by age");

Collections.sort(al,new AgeComparator());
Iterator itr2=al.iterator();
while(itr2.hasNext()){
Student st=(Student)itr2.next();
System.out.println(st.rollno+" "+st.name+" "+st.age);
}


}
}

Output:

Output

Sorting by Name
       106 Ajay 27
       105 Jai 21
       101 Vijay 23
       
       Sorting by age       
       105 Jai 21
       101 Vijay 23
       106 Ajay 27

Java Comparator Example (Generic)

Student.java

Example

class Student{
int rollno;
String name;
int age;
Student(int rollno,String name,int age){
this.rollno=rollno;
this.name=name;
this.age=age;
}
}

AgeComparator.java

Example

import java.util.*;
class AgeComparator implements Comparator<Student>{
public int compare(Student s1,Student s2){
if(s1.age==s2.age)
return 0;
else if(s1.age>s2.age)
return 1;
else
return -1;
}
}

NameComparator.java

The provided class offers comparison functionality that relies on names. In this scenario, the compareTo method of the String class is utilized to handle the comparison logic internally.

Example

import java.util.*;
class NameComparator implements Comparator<Student>{
public int compare(Student s1,Student s2){
return s1.name.compareTo(s2.name);
}
}

Simple.java

Within this course, we are outputting the object values by arranging them in ascending order based on both name and age criteria.

Example

import java.util.*;
import java.io.*;
class Simple{
public static void main(String args[]){

ArrayList<Student> al=new ArrayList<Student>();
al.add(new Student(101,"Vijay",23));
al.add(new Student(106,"Ajay",27));
al.add(new Student(105,"Jai",21));

System.out.println("Sorting by Name");

Collections.sort(al,new NameComparator());
for(Student st: al){
System.out.println(st.rollno+" "+st.name+" "+st.age);
}

System.out.println("Sorting by age");

Collections.sort(al,new AgeComparator());
for(Student st: al){
System.out.println(st.rollno+" "+st.name+" "+st.age);
}
}
}

Output:

Output

Sorting by Name
       106 Ajay 27
       105 Jai 21
       101 Vijay 23

       Sorting by age     
       105 Jai 21
       101 Vijay 23
       106 Ajay 27

Java 8 Comparator interface

The Comparator interface in Java 8 is classified as a functional interface, which implies it consists of just a single abstract method. Consequently, we have the capability to designate the Comparator interface as the target for a lambda expression or a method reference.

Methods of Java 8 Comparator Interface

Method Description
int compare(T o1, T o2) It compares the first object with second object.
static static <T> Comparator<T> comparing(Function<? super T, ? extends Comparable<?>> keyExtractor)> ComparatorComparator comparing(FunctionFunction<T, ? extends Comparable<?>> keyExtractor) It accepts a function that extracts a Comparable sort key from a type T, and returns a Comparatorthat compares by that sort key.
static <T> ComparatorComparator comparing(FunctionFunction<? super T, ? extends Comparable<?>> keyExtractor, ComparatorComparator<T> keyComparator) It accepts a function that extracts a sort key from a type T, and returns a Comparatorthat compares by that sort key using the specified Comparator.
static static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) ComparatorComparator comparingDouble(ToDoubleFunction<? super T> keyExtractor) It accepts a function that extracts a double sort key from a type T, and returns a Comparatorthat compares by that sort key.
static static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) ComparatorComparator<T> comparingInt(ToIntFunctionToIntFunction keyExtractor) It accepts a function that extracts an int sort key from a type T, and returns a Comparatorthat compares by that sort key.
static <T> ComparatorComparator<T> comparingLong(ToLongFunctionToLongFunction<? super T> keyExtractor) It accepts a function that extracts a long sort key from a type T, and returns a Comparatorthat compares by that sort key.
boolean equals(Object obj) It is used to compare the current object with the specified object.
static <T>> ComparatorComparator<T> naturalOrder() It returns a comparator that compares Comparable objects in natural order.
static <T> ComparatorComparator<T> nullsFirst(ComparatorComparator<T> comparator) It returns a comparator that treats null to be less than non-null elements.
static static <T> Comparator<T> nullsLast(Comparator<T> comparator) ComparatorComparator<T> nullsLast(ComparatorComparator<T> comparator) It returns a comparator that treats null to be greater than non-null elements.
default Comparator<T> reversed() It returns comparator that contains reverse ordering of the provided comparator.
static <T>> ComparatorComparator<T> reverseOrder() It returns comparator that contains reverse of natural ordering.
default ComparatorComparator<T> thenComparing(ComparatorComparator<T> other) It returns a lexicographic-order comparator with another comparator.
default Comparator<T>> ComparatorComparator thenComparing(FunctionFunction<T, ? extends Comparable<?>> keyExtractor) It returns a lexicographic-order comparator with a function that extracts a Comparable sort key.
default default <T> Comparator<T> thenComparing(Function<? super T, ? extends Comparable<?>> keyExtractor, Comparator<? super T> keyComparator) ComparatorComparator<T> thenComparing(FunctionFunction<T, ? extends Comparable<?>> keyExtractor, ComparatorComparator<T> keyComparator) It 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) It accepts a function that extracts a double sort key from a type T, and returns a Comparatorthat compares by that sort key.
static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) It accepts a function that extracts an int sort key from a type T, and returns a Comparatorthat compares by that sort key.
static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) It accepts a function that extracts a long sort key from a type T, and returns a Comparatorthat compares by that sort key.
boolean equals(Object obj) It is used to compare the current object with the specified object.
static <T extends Comparable<? super T>> Comparator<T> naturalOrder() It returns a comparator that compares Comparable objects in natural order.
static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) It returns a comparator that treats null to be less than non-null elements.
static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) It returns a comparator that treats null to be greater than non-null elements.
default Comparator<T> reversed() It returns comparator that contains reverse ordering of the provided comparator.
static <T extends Comparable<? super T>> Comparator<T> reverseOrder() It returns comparator that contains reverse of natural ordering.
default Comparator<T> thenComparing(Comparator<? super T> other) It returns a lexicographic-order comparator with another comparator.
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 double sort key.
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) It returns a lexicographic-order comparator with a function that extracts a int sort key.
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) It returns a lexicographic-order comparator with a function that extracts a int sort key.
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) It returns a lexicographic-order comparator with a function that extracts a long sort key.

Java 8 Comparator Example

Let's explore an example demonstrating the sorting of items in a List based on age and name criteria.

File: Student.java

Example

class Student {  
   int rollno;  
   String name;  
  int age;  
    Student(int rollno,String name,int age){  
    this.rollno=rollno;  
    this.name=name;  
    this.age=age;  
    }

	public int getRollno() {
		return rollno;
	}

	public void setRollno(int rollno) {
		this.rollno = rollno;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

    }

File: TestSort1.java

Example

import java.util.*;  
    public class TestSort1{  
    public static void main(String args[]){  
    ArrayList<Student> al=new ArrayList<Student>();  
    al.add(new Student(101,"Vijay",23));  
    al.add(new Student(106,"Ajay",27));  
    al.add(new Student(105,"Jai",21)); 
	//Sorting elements on the basis of name
    Comparator<Student> cm1=Comparator.comparing(Student::getName);
     Collections.sort(al,cm1);
     System.out.println("Sorting by Name");
     for(Student st: al){
    	 System.out.println(st.rollno+" "+st.name+" "+st.age);
    	 }
     //Sorting elements on the basis of age
      Comparator<Student> cm2=Comparator.comparing(Student::getAge);
	 Collections.sort(al,cm2);
     System.out.println("Sorting by Age");
     for(Student st: al){
    	 System.out.println(st.rollno+" "+st.name+" "+st.age);
    	 }  
    }  
    }

Output:

Output

Sorting by Name
106 Ajay 27
105 Jai 21
101 Vijay 23
Sorting by Age
105 Jai 21
101 Vijay 23
106 Ajay 27

Java 8 Comparator Example: nullsFirst and nullsLast method

In this case, we are arranging the collection of items that includes null values.

File: Student.java

Example

class Student {  
   int rollno;  
   String name;  
  int age;  
    Student(int rollno,String name,int age){  
    this.rollno=rollno;  
    this.name=name;  
    this.age=age;  
    }
	public int getRollno() {
		return rollno;
	}
	public void setRollno(int rollno) {
		this.rollno = rollno;
	}
	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
    }

File: TestSort2.java

Example

import java.util.*;  
    public class TestSort2{  
    public static void main(String args[]){  
    ArrayList<Student> al=new ArrayList<Student>();  
    al.add(new Student(101,"Vijay",23));  
    al.add(new Student(106,"Ajay",27));  
    al.add(new Student(105,null,21));  
    Comparator<Student> cm1=Comparator.comparing(Student::getName,Comparator.nullsFirst(String::compareTo));
     Collections.sort(al,cm1);
     System.out.println("Considers null to be less than non-null");
     for(Student st: al){
    	 System.out.println(st.rollno+" "+st.name+" "+st.age);
    	 }
     Comparator<Student> cm2=Comparator.comparing(Student::getName,Comparator.nullsLast(String::compareTo));
     Collections.sort(al,cm2);
     System.out.println("Considers null to be greater than non-null");
     for(Student st: al){
    	 System.out.println(st.rollno+" "+st.name+" "+st.age);
    	 }
    }  
    }

Output:

Output

Considers null to be less than non-null
105 null 21
106 Ajay 27
101 Vijay 23
Considers null to be greater than non-null
106 Ajay 27
101 Vijay 23
105 null 21

Input Required

This code uses input(). Please provide values below: