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 ageFor 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
EasyLet'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), andsalary(double). Include a constructor to initialize all fields and getter methods for each. OverridetoString()to return:[name] ([department]) - $[salary]SalaryComparator.java: Create a comparator that sorts employees by salary in descending order (highest paid first). Implement theComparator<Employee>interface and itscompare()method. UseDouble.compare()for safe comparison of salary values.NameComparator.java: Create another comparator that sorts employees alphabetically by name in ascending order (A to Z). ImplementComparator<Employee>and use the String'scompareTo()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,salaryCreate an
ArrayListof employees, then demonstrate both sorting approaches:- First, sort by salary using your
SalaryComparatorand print each employee - Print an empty line
- Then sort by name using your
NameComparatorand print each employee
- First, sort by salary using your
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
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System