Menu
Coddy logo textTech

Comparator Interface

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 45 of 87.

While Comparable defines a class's natural ordering, sometimes you need to sort objects in different ways. The Comparator interface lets you create separate comparison logic without modifying the original class.

A Comparator is an external object that compares two objects of the same type. This is useful when you want multiple sorting options or when you can't modify the class itself:

import java.util.Comparator;

class NameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

You can then pass the comparator to sorting methods:

List<Person> people = new ArrayList<>();
people.add(new Person("Charlie", 30));
people.add(new Person("Alice", 25));

Collections.sort(people, new NameComparator());  // Sorted by name
Collections.sort(people, new AgeComparator());   // Sorted by age

For concise code, you can use lambda expressions since Comparator is a functional interface:

Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));

The key difference: Comparable is implemented by the class being compared and defines one natural order, while Comparator is a separate class that can define unlimited custom orderings.

challenge icon

Challenge

Easy

Let's build an employee sorting system that demonstrates the power of the Comparator interface. You'll create multiple comparators to sort employees in different ways—by salary and by name—without modifying the Employee class itself.

You'll organize your code across four files:

  • Employee.java: Create a class representing an employee with three private fields: name (String), department (String), and salary (double). Include a constructor to initialize all fields and getter methods for each. Override toString() to return: [name] ([department]) - $[salary]
  • SalaryComparator.java: Create a comparator that sorts employees by salary in descending order (highest paid first). Implement the Comparator<Employee> interface and its compare() method. Use Double.compare() for safe comparison of salary values.
  • NameComparator.java: Create another comparator that sorts employees alphabetically by name in ascending order (A to Z). Implement Comparator<Employee> and use the String's compareTo() method for comparison.
  • Main.java: Bring everything together by creating a list of employees and sorting them using your comparators. You'll receive input for three employees, each on a separate line in the format: name,department,salary

    Create an ArrayList of employees, then demonstrate both sorting approaches:

    1. First, sort by salary using your SalaryComparator and print each employee
    2. Print an empty line
    3. Then sort by name using your NameComparator and print each employee

You will receive three lines of input, each containing employee data in the format: name,department,salary

For example, an input line might look like: Alice,Engineering,75000.0

Remember to import java.util.Comparator in your comparator files, and java.util.ArrayList, java.util.Collections, and java.util.Scanner in your Main file. Notice how comparators let you define multiple sorting strategies externally—the Employee class doesn't need to know anything about how it might be sorted!

Cheat sheet

The Comparator interface allows you to create external comparison logic for sorting objects without modifying the original class. This is useful when you need multiple sorting options.

A Comparator compares two objects of the same type by implementing the compare() method:

import java.util.Comparator;

class NameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

Pass the comparator to sorting methods:

Collections.sort(people, new NameComparator());

You can use lambda expressions for concise code since Comparator is a functional interface:

Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));

For comparing numeric values, use wrapper class methods like Double.compare() for safe comparison:

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

Key difference: Comparable defines one natural order within the class itself, while Comparator is a separate class that can define unlimited custom orderings externally.

Try it yourself

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Read three employees from input
        // Each line format: name,department,salary
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: Parse each line and create Employee objects
        // Hint: Use split(",") to separate the values
        
        // TODO: Create an ArrayList of employees and add all three
        
        // TODO: Sort by salary using SalaryComparator and print each employee
        // Hint: Use Collections.sort(list, comparator)
        
        // TODO: Print an empty line
        
        // TODO: Sort by name using NameComparator and print each employee
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming