Table of contents
1.
Introduction
2.
What is the Java Comparator Interface?
3.
Methods of Comparator Interface in Java
3.1.
compare() Method
3.1.1.
Syntax 
3.1.2.
Return Value 
3.2.
equals() Method
3.2.1.
Syntax
3.2.2.
Return Value 
4.
Java Comparator Interface example
5.
Java Comparator Interface to Sort an Object
5.1.
Java
6.
Java 8 Comparator Interface
7.
Methods of Java 8 Comparator Interface
8.
Java 8 Comparator Example
8.1.
Java
9.
Java Comparable Vs Java Comparator
10.
Frequently Asked Questions
10.1.
What is Java Comparator for comparable?
10.2.
What is the Comparator functional interface?
10.3.
Why use Comparator in Java?
10.4.
Is Comparator a functional interface?
10.5.
How to compare names using Comparator in Java?
11.
Conclusion
Last Updated: Oct 7, 2024
Medium

Comparator Interface in Java

Author Shiva
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Java Comparator is a part of the Java Collection Framework. The Java Collection framework is a large collection of classes and interfaces that provide a versatile architecture for storing, organizing, and manipulating groupings of objects. It provides a diverse set of data structures and algorithms for performing actions on collections of items, such as searching, sorting, insertion, manipulation, and deletion.

java comparator

What is the Java Comparator Interface?

The Comparator interface in the Java Collections Framework provides a way to order objects of user-defined classes based on specific criteria. It allows for custom comparison logic, enabling sorting operations on objects that may belong to different classes.

The following are some use cases of the Java Comparator Interface:-

  • Customized Sorting: The primary advantage of the Comparator interface is that it allows you to define custom sorting orders for objects that may not have a natural ordering.
     
  • Separate Sorting Logic: With the Comparator interface, you can separate the sorting logic from the class definition itself. This makes your code cleaner and more maintainable.
     
  • Multiple Sorting Orders: You can define multiple Comparator implementations for the same class, each representing a different sorting order. This allows you to sort the same set of objects in various ways without modifying the original class.
     

Now, let us take a look at the methods of the Java comparator interface.

Methods of Comparator Interface in Java

The Comparator interface contains two methods:

  • Compare Method
     
  • Equals Method

compare() Method

This method compares two objects, obj1, and obj2, and returns an integer value to indicate their relative order. 

Syntax 

public int compare(Object obj1, Object obj2)

 

Return Value 

The return value follows the following convention:

  • If obj1 should be placed before obj2, a negative value is returned.
     
  • If obj1 should be placed after obj2, a positive value is returned.
     
  • If obj1 and obj2 are considered equal in terms of ordering, zero is returned.

equals() Method

This method checks whether the invoking Comparator is equal to the specified element. It returns true if the element is also a Comparator object and both Comparators impose the same ordering.

By implementing the Comparator interface and defining the compare() method, we can specify how objects should be ordered based on specific attributes or data members. For example, we can create a Comparator for a Student class that compares students based on their GPA or age.

Syntax

public boolean equals(Object obj)

 

Return Value 

  • true: If equals() returns true, it means that the two Comparator instances are the same and correspond to the same memory object.
     
  • false: If equals() returns false, it indicates that the two Comparator instances are not the same and correspond to different objects in memory.

Java Comparator Interface example

Here is an example of how to use the Java Comparator Interface: 

import java.util.Comparator;

class LengthComparator implements Comparator<String> {
    // Compare strings based on their length
    public int compare(String str1, String str2) {
        return Integer.compare(str1.length(), str2.length());
    }

    // Optional: Overriding equals() to check reference equality
    @Override
    public boolean equals(Object obj) {
        return this == obj;
    }
}

class HelloWorld {
    public static void main(String[] args) {
        LengthComparator comparator = new LengthComparator();

        String string1 = "Coding";
        String string2 = "Ninjas"; // Use correct quotes

        // Compare the lengths of the two strings
        int result = comparator.compare(string1, string2);
        
        // Check if the comparator is equal to itself (this will always be true)
        boolean isEqual = comparator.equals(comparator);

        // Print the results
        System.out.println("Comparison result: " + result); 
        System.out.println("Are Comparators equal? " + isEqual); 
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output

Comparison result: 0
Are Comparators equal? true

 

In this example, we have a custom LengthComparator class that implements the Comparator interface and is used to compare the lengths of String objects. The compare() method compares the lengths of two strings by calling “Integer.compare()”. The equals() method simply determines whether the two comparator instances (this and obj) are equal.

In the main() method, we build a comparator instance of the LengthComparator class. In addition, we make two String objects, string1, and string2. We compare their lengths using the compare() method and save the result in the result variable. Because the length of both strings is equal, therefore the output is 0. The equals() method is then used to determine whether the comparator is equal to itself, and the result is placed in the isEqual variable. Because this and obj are referring to the same memory location, therefore the output is true.

Java Comparator Interface to Sort an Object

We can sort objects in Java using custom logic. We can do this by overriding compare method in the Comparator interface.

  • Java

Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class HelloWorld {
   public static void main(String[] args) {
       List<Integer> arr = new ArrayList<>();
       arr.add(2);
       arr.add(0);
       arr.add(6);
       arr.add(3);
       arr.add(9);
      
       // Sort the list in descending order
       Collections.sort(arr, new Comparator<Integer>() {
           @Override
           public int compare(Integer num1, Integer num2) {
               // Sorting in descending order
               return num2-num1;
           }
       });
       System.out.println(arr);
   }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

[9, 6, 3, 2, 0]

 

Explanation: 

In the example above, we have an array list named arr. After inserting sufficient elements, we override the compare function of the Comparator interface. To implement descending order logic, we return num2-num1. The compare method is supposed to return positive and negative or zero. It will be only positive if the second parameter is greater than the first one, which basically translates to num2 being supposed to place before num1.

Java 8 Comparator Interface

In Java 8, the Comparator interface received significant enhancements to increase its power and flexibility, which makes it more functional and easier to use in modern Java applications. A key feature introduced in Java 8 is the ability to define Comparator instances using lambda expressions, which greatly simplifies the implementation of comparison logic for sorting collections.

A few important points about the Java 8 Comparator interface:

  • Functional Interface: The Comparator interface is a functional interface, which means it has a single abstract method. In this case, the abstract method is compare(T o1, T o2), which compares two objects and returns an integer value indicating their relative order.
  • Lambda Expressions: With Java 8, you can use lambda expressions to create Comparator instances inline, without the need for an explicit class implementation. This makes the code more concise and readable.

Methods of Java 8 Comparator Interface

1. Default Methods: Java 8 introduced default methods in interfaces and the Comparator interface benefits from this feature. It provides several default methods that allow you to create Comparators based on various criteria:
  - reversed(): Returns a Comparator that imposes the reverse ordering of the original Comparator.
  - thenComparing(Comparator other): Returns a Comparator that first applies the original Comparator, and if the objects are equal, applies the provided Comparator.
  - thenComparing(Function keyExtractor): Returns a Comparator that first applies the original Comparator, and if the objects are equal, compares them based on the extracted key using the natural ordering.
  - thenComparingInt(ToIntFunction keyExtractor), thenComparingLong(ToLongFunction keyExtractor), thenComparingDouble(ToDoubleFunction keyExtractor): Similar to thenComparing(Function), but specifically for int, long, and double keys.

2. Static Methods: The Comparator interface also provides static methods for creating Comparators based on different criteria:
  - comparing(Function keyExtractor): Creates a Comparator based on the extracted key using the natural ordering.
  - comparing(Function keyExtractor, Comparator keyComparator): Creates a Comparator based on the extracted key using the provided Comparator.
  - comparingInt(ToIntFunction keyExtractor), comparingLong(ToLongFunction keyExtractor), comparingDouble(ToDoubleFunction keyExtractor): Similar to comparing(Function), but specifically for int, long, and double keys.
  - naturalOrder(): Returns a Comparator that compares objects using their natural ordering (defined by the compareTo() method).
  - nullsFirst(Comparator comparator), nullsLast(Comparator comparator): Returns a Comparator that treats null values as either first or last in the ordering, respectively.

Java 8 Comparator Example

  • Java

Java

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

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

public class ComparatorExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 20));
people.add(new Person("David", 35));

// Sort by name using lambda expression
people.sort(Comparator.comparing(Person::getName));
System.out.println("Sorted by name: " + people);

// Sort by age using lambda expression
people.sort(Comparator.comparingInt(Person::getAge));
System.out.println("Sorted by age: " + people);

// Sort by name length using lambda expression
people.sort(Comparator.comparingInt(p -> p.getName().length()));
System.out.println("Sorted by name length: " + people);

// Sort by age in reverse order using default method
people.sort(Comparator.comparingInt(Person::getAge).reversed());
System.out.println("Sorted by age in reverse order: " + people);

// Sort by name and then by age using default methods
people.sort(Comparator.comparing(Person::getName).thenComparingInt(Person::getAge));
System.out.println("Sorted by name and then by age: " + people);
}
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Sorted by name: [Person{name='Alice', age=25}, Person{name='Bob', age=30}, Person{name='Charlie', age=20}, Person{name='David', age=35}] 

Sorted by age: [Person{name='Charlie', age=20}, Person{name='Alice', age=25}, Person{name='Bob', age=30}, Person{name='David', age=35}] 

Sorted by name length: [Person{name='Bob', age=30}, Person{name='Alice', age=25}, Person{name='David', age=35}, Person{name='Charlie', age=20}] 

Sorted by age in reverse order: [Person{name='David', age=35}, Person{name='Bob', age=30}, Person{name='Alice', age=25}, Person{name='Charlie', age=20}] 

Sorted by name and then by age: [Person{name='Alice', age=25}, Person{name='Bob', age=30}, Person{name='Charlie', age=20}, Person{name='David', age=35}]

 

In this example:

1. We define a `Person` class with `name` and `age` attributes, along with getter methods and a `toString()` method for proper representation.

2. In the `main` method, we create a list of `Person` objects.

3. We showed different ways to sort the list using Comparators:
  - `people.sort(Comparator.comparing(Person::getName))`: Sorts the list by name using a lambda expression that extracts the name from each Person object.
  - `people.sort(Comparator.comparingInt(Person::getAge))`: Sorts the list by age using a lambda expression that extracts the age from each Person object.
  - `people.sort(Comparator.comparingInt(p -> p.getName().length()))`: Sorts the list by the length of the name using a lambda expression.
  - `people.sort(Comparator.comparingInt(Person::getAge).reversed())`: Sorts the list by age in reverse order using the `reversed()` default method.
  - `people.sort(Comparator.comparing(Person::getName).thenComparingInt(Person::getAge))`: Sorts the list first by name and then by age using the `thenComparingInt()` default method.

4. After each sorting operation, we print the sorted list to observe the results.

Java Comparable Vs Java Comparator

Here’s a detailed difference between comparable and comparator in Java:

ParametersComparableComparator
ObjectiveIt defines the natural order of objects within the class.It provides custom comparison logic to sort objects.
ImplementationIt requires modification of the class.compare() method of the Comparator Interface gets overridden.
InterfaceThe class itself implements it.It is implemented separately.
Methodpublic int compareTo(Object obj)public int compare(Object obj1, Object obj2):
Null ValuesNull values should be handled by the compareTo() method.Null values will be handled as per the custom logic defined.
Multiple ImplementationOnly one natural ordering can be defined per class.Multiple implementations can be defined.

Frequently Asked Questions

What is Java Comparator for comparable?

Java's Comparator is used to define custom comparison logic, distinct from a class's natural ordering defined by Comparable.

What is the Comparator functional interface?

The Comparator functional interface in Java provides a way to define custom comparison logic for classes that do not implement Comparable. It allows sorting and comparison of objects based on specific criteria defined by the programmer.

Why use Comparator in Java?

The Comparable interface is used in Java to establish a natural ordering for objects of a class. This enables sorting collections of objects and provides a standard way to compare instances of the class.

Is Comparator a functional interface?

Yes, Comparator is a functional interface in Java, allowing implementation via lambda expressions.

How to compare names using Comparator in Java?

To compare names using Comparator in Java: Comparator<Person> byName = Comparator.comparing(Person::getName);

Conclusion

This article covered everything you needed to know about Java Comparator Interface in Java Collection. We covered its methods, compare and equals with examples. We also saw how to perform sorting using a comparator and the difference between comparable and comparator.

Recommended Readings:

 

Do check out some of the Popular Interview Problems from Top companies like AmazonAdobeGoogle, etc., on Naukri Code 360.

Cheers!

Live masterclass