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.