From 763d55e19c755cd912bcdead027891d6b698863d Mon Sep 17 00:00:00 2001 From: Sriparno Roy Date: Tue, 8 Jul 2025 13:49:29 +0530 Subject: [PATCH] [Edit] Java: Comparator --- .../java/concepts/comparator/comparator.md | 159 +++++++++++------- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/content/java/concepts/comparator/comparator.md b/content/java/concepts/comparator/comparator.md index b8262c6ea36..8142b328d1e 100644 --- a/content/java/concepts/comparator/comparator.md +++ b/content/java/concepts/comparator/comparator.md @@ -14,7 +14,7 @@ CatalogContent: - 'paths/computer-science' --- -The **`Comparator`** interface is used to order objects of an arbitrary [class](https://www.codecademy.com/resources/docs/java/classes). It is not to be confused with the [`Comparable`](https://www.codecademy.com/resources/docs/java/comparable) interface, which is implemented by the class to be sorted. The `Comparator` interface is implemented in a separate class. +In Java, the **`Comparator`** interface is used to order objects of an arbitrary [class](https://www.codecademy.com/resources/docs/java/classes). It is not to be confused with the [`Comparable`](https://www.codecademy.com/resources/docs/java/comparable) interface, which is implemented by the class to be sorted. The `Comparator` interface is implemented in a separate class. ## Syntax @@ -29,97 +29,138 @@ class MyComparator implements Comparator { } ``` -Applying the `Comparator` interface to a class, `MyComparator`, requires the `implements` keyword (e.g., `Comparator`). This interface has a `.compare()` method that returns an `int` value based on whether two `MyClass` instances, `a` and `b`, can be logically sorted. +Applying the `Comparator` interface to a class, `MyComparator`, requires the `implements` keyword (e.g., `Comparator`). This interface has a `.compare()` method, which returns an `int` value based on whether two `MyClass` instances, `a` and `b`, can be logically sorted: | Return Value | Meaning | | :----------: | ---------------------------------------------- | -| `>= 1` | first object instance > second object instance | -| `0` | first object instance = second object instance | -| `<= -1` | first object instance < second object instance | +| `>= 1` | First object instance > Second object instance | +| `0` | First object instance = Second object instance | +| `<= -1` | First object instance < Second object instance | A `Comparator` class can be passed as an argument to methods such as [`Arrays.sort()`](https://www.codecademy.com/resources/docs/java/arrays/sort) and `Collections.sort()` to specify the sort order, potentially overriding the natural sort order defined by the class’s own `.compareTo()` method. -## Example +## Example 1: Sort List of Strings by Length -The following example showcases the `Comparator` interface. First, an `Employee` class is defined: +In this example, the `StringLengthComparator` class is used to compare two strings based on their length. This is useful when the sorting logic is used in multiple places or needs to be unit-tested: ```java -// Employee.java -public class Employee { - String firstName; - String lastName; +import java.util.*; - // Constructor sets firstName and lastName - public Employee(String first, String last) - { - this.firstName = first; - this.lastName = last; +class StringLengthComparator implements Comparator { + public int compare(String s1, String s2) { + return s1.length() - s2.length(); // Ascending by length } +} - // User-friendly output when printed. - public String toString() - { - return "( " + lastName + ", " + firstName + " )"; +public class StringLengthSort { + public static void main(String[] args) { + List words = Arrays.asList("banana", "apple", "pear", "kiwi"); + + // Sort using comparator + Collections.sort(words, new StringLengthComparator()); + + System.out.println("Sorted by length: " + words); } } ``` -The next snippet defines an `EmployeeSort` class that implements the `Comparator` interface and overrides its `.compare()` method to sort based on `lastName` and then on `firstName`: +Here is the output: + +```shell +Sorted by length: [pear, kiwi, apple, banana] +``` + +## Example 2: Sort Custom Objects by Field + +In this example, `SalaryComparator` is a reusable class for comparing employees based on their salary and `Collections.sort()` applies the comparator to arrange employees in ascending order: ```java import java.util.*; -// EmployeeSort.java -public class EmployeeSort implements Comparator { +class Employee { + String name; + int salary; - // Implement the Comparator interface - @Override public int compare(Employee valueA, Employee valueB) - { - if (valueA.lastName.compareTo(valueB.lastName) != 0) { - // If lastNames are different, compare lastName - return valueA.lastName.compareTo(valueB.lastName); - } else { - // If lastNames are the same, compare firstName - return valueA.firstName.compareTo(valueB.firstName); - } + Employee(String name, int salary) { + this.name = name; + this.salary = salary; + } + + public String toString() { + return name + ": " + salary; + } +} + +// Comparator to sort employees by salary +class SalaryComparator implements Comparator { + public int compare(Employee e1, Employee e2) { + return e1.salary - e2.salary; // Ascending order + } +} + +public class EmployeeSort { + public static void main(String[] args) { + List list = new ArrayList<>(); + list.add(new Employee("Alice", 70000)); + list.add(new Employee("Bob", 50000)); + list.add(new Employee("Charlie", 60000)); + + // Sort using SalaryComparator + Collections.sort(list, new SalaryComparator()); + + System.out.println("Sorted by salary: " + list); } } ``` -This last snippet demonstrates the `Comparator` interface: +Here is the output: + +```shell +Sorted by salary: [Bob: 50000, Charlie: 60000, Alice: 70000] +``` + +## Example 3: Sort in Reverse Order + +In this example, the `ReverseIntegerComparator` class reverses the natural ordering of integers. It's useful when built-in methods like `Comparator.reverseOrder()` are not allowed or available: ```java import java.util.*; -// SortExample.java -public class SortExample { - public static void main(String[] args) - { - // Set up array with a few Employee classes - Employee a[] = new Employee[5]; - a[0] = new Employee("Kirk","Douglas"); - a[1] = new Employee("Mel","Brooks"); - a[2] = new Employee("Jane","Fonda"); - a[3] = new Employee("Henry","Fonda"); - a[4] = new Employee("Michael","Douglas"); - - // Use .sort() method with Comparable class. - Arrays.sort(a, new EmployeeSort()); - - // Print out the sorted Employees - for (int i=0; i < a.length; i++) { - System.out.println(a[i]); - } +class ReverseIntegerComparator implements Comparator { + public int compare(Integer a, Integer b) { + return b - a; // descending order + } +} + +public class ReverseSortExample { + public static void main(String[] args) { + List numbers = Arrays.asList(5, 1, 3, 8, 2); + + // Reverse sort using explicit comparator + Collections.sort(numbers, new ReverseIntegerComparator()); + + System.out.println("Reverse sorted: " + numbers); } } ``` -This example results in the following output: +Here is the output: ```shell -( Brooks, Mel ) -( Douglas, Kirk ) -( Douglas, Michael ) -( Fonda, Henry ) -( Fonda, Jane ) +Reverse sorted: [8, 5, 3, 2, 1] ``` + +## Frequently Asked Questions + +### 1. What is the difference between `Comparator` and `Comparable`? + +- `Comparable` is implemented by a class to define its natural ordering. +- `Comparator` is used to define external and multiple sorting strategies. + +### 2. Can a class have multiple comparators? + +Yes. You can create multiple `Comparator` classes to sort objects differently—for example, by name, salary, or ID. + +### 3. Is `Comparator` a functional interface? + +Yes. Since Java 8, you can utilize lambda expressions to implement comparators concisely.