Comparable vs Comparator in Java Explained with Real Examples and Sorting Logic

Understand the difference between Comparable and Comparator in Java with real-world examples, sorting logic, and complex use cases used in production systems.

Comparable vs Comparator in Java

In Java, sorting objects is a common requirement. To achieve custom sorting, Java provides two important interfaces: Comparable and Comparator. Both are used to define sorting logic, but in different ways.

1. Comparable Interface (Natural Ordering)

Comparable is used to define the natural ordering of objects. It modifies the class itself using the compareTo() method.

  • Used when single default sorting logic is needed
  • Implemented inside the class
  • Method: compareTo(Object o)

Example: Sorting Employees by ID (Natural Order)

import java.util.*;

class Employee implements Comparable<Employee> {
    int id;
    String name;

    Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int compareTo(Employee other) {
        return this.id - other.id; // Ascending order by ID
    }

    @Override
    public String toString() {
        return id + " " + name;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Employee> list = new ArrayList<>();
        list.add(new Employee(3, "A"));
        list.add(new Employee(1, "B"));
        list.add(new Employee(2, "C"));

        Collections.sort(list);
        System.out.println(list);
    }
}

2. Comparator Interface (Custom Sorting)

Comparator is used when we need multiple sorting strategies without modifying the original class.

  • Used for multiple sorting logics
  • Implemented outside the class
  • Method: compare(Object o1, Object o2)

Example: Sorting Employees by Name

import java.util.*;

class Employee {
    int id;
    String name;

    Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return id + " " + name;
    }
}

class NameComparator implements Comparator<Employee> {
    public int compare(Employee e1, Employee e2) {
        return e1.name.compareTo(e2.name);
    }
}

public class Main {
    public static void main(String[] args) {
        List<Employee> list = new ArrayList<>();
        list.add(new Employee(3, "Zack"));
        list.add(new Employee(1, "Alex"));
        list.add(new Employee(2, "John"));

        Collections.sort(list, new NameComparator());
        System.out.println(list);
    }
}

🔥 Complex Real-World Example (Multiple Sorting Rules)

In real systems like HR dashboards or e-commerce admin panels, sorting is required in multiple ways (by ID, name, salary, etc.). Comparator is heavily used here.

import java.util.*;

class Employee {
    int id;
    String name;
    double salary;

    Employee(int id, String name, double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return id + " " + name + " " + salary;
    }
}

class SalaryComparator implements Comparator<Employee> {
    public int compare(Employee e1, Employee e2) {
        return Double.compare(e1.salary, e2.salary);
    }
}

public class Main {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();

        employees.add(new Employee(1, "A", 50000));
        employees.add(new Employee(2, "B", 30000));
        employees.add(new Employee(3, "C", 70000));

        // Sort by salary
        Collections.sort(employees, new SalaryComparator());

        System.out.println(employees);
    }
}

Real-World Use Cases

  • E-commerce product sorting (price, rating, popularity)
  • HR systems (salary, experience, joining date)
  • Banking apps (transaction sorting by date)
  • Admin dashboards (multi-field sorting filters)

Difference Between Comparable and Comparator

Final Summary

  • Comparable → used for default sorting (natural order)
  • Comparator → used for custom multiple sorting logics
  • Comparable modifies class itself
  • Comparator keeps sorting logic separate and reusable

In modern Java applications, Comparator is more commonly used because it provides flexibility without changing the original class structure.

Real-World Insight

In large-scale systems like Amazon or banking dashboards, Comparator is heavily used because data needs to be sorted dynamically based on user preferences like price, rating, date, or salary.