Comparable Interface in Java

Table of Contents

  1. Introduction
  2. Comparable vs Comparator
  3. Method Signature
  4. Implementing Comparable
  5. Natural Ordering
  6. Using with Collections
  7. Best Practices
  8. Common Examples
  9. Advanced Topics
  10. Complete Examples

Introduction

The Comparable interface in Java is used to define the natural ordering of objects. It allows objects to be compared to each other and sorted automatically by collections like TreeSet, TreeMap, and when using Collections.sort().

Key Points:

  • Package: java.lang.Comparable
  • Single method: compareTo(T o)
  • Natural ordering: Defines how objects should be ordered by default
  • Used by: Collections.sort(), TreeSet, TreeMap, etc.

Comparable vs Comparator

Comparison Table:

AspectComparableComparator
Packagejava.langjava.util
MethodcompareTo(T o)compare(T o1, T o2)
UsageNatural orderingCustom ordering
ModificationModifies the classDoesn't modify the class
Multiple sortsOnly one natural orderMultiple comparators
InstanceObject itselfSeparate class

When to Use:

  • Use Comparable for natural, default ordering
  • Use Comparator for alternative ordering strategies

Method Signature

public interface Comparable<T> {
int compareTo(T o);
}

Return Value Meaning:

  • Negative integer: This object is less than the specified object
  • Zero: This object is equal to the specified object
  • Positive integer: This object is greater than the specified object

Implementing Comparable

Basic Implementation:

class Student implements Comparable<Student> {
private int id;
private String name;
private double gpa;
public Student(int id, String name, double gpa) {
this.id = id;
this.name = name;
this.gpa = gpa;
}
@Override
public int compareTo(Student other) {
return Integer.compare(this.id, other.id);
}
// Getters, toString, etc.
public int getId() { return id; }
public String getName() { return name; }
public double getGpa() { return gpa; }
@Override
public String toString() {
return String.format("Student{id=%d, name='%s', gpa=%.2f}", id, name, gpa);
}
}

Natural Ordering

Different Natural Ordering Strategies:

import java.util.*;
// Natural ordering by name
class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Natural ordering by name
@Override
public int compareTo(Person other) {
return this.name.compareTo(other.name);
}
@Override
public String toString() {
return String.format("Person{name='%-8s', age=%d}", name, age);
}
}
// Natural ordering by age
class Employee implements Comparable<Employee> {
private String name;
private int age;
private double salary;
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
// Natural ordering by age (youngest to oldest)
@Override
public int compareTo(Employee other) {
return Integer.compare(this.age, other.age);
}
@Override
public String toString() {
return String.format("Employee{name='%-6s', age=%2d, salary=$%7.2f}", 
name, age, salary);
}
}
// Natural ordering by multiple fields
class Product implements Comparable<Product> {
private String category;
private String name;
private double price;
public Product(String category, String name, double price) {
this.category = category;
this.name = name;
this.price = price;
}
// Natural ordering: first by category, then by name
@Override
public int compareTo(Product other) {
int categoryCompare = this.category.compareTo(other.category);
if (categoryCompare != 0) {
return categoryCompare;
}
return this.name.compareTo(other.name);
}
@Override
public String toString() {
return String.format("Product{category='%-12s', name='%-10s', price=$%6.2f}", 
category, name, price);
}
}
public class NaturalOrderingExamples {
public static void main(String[] args) {
// Person - natural ordering by name
List<Person> people = Arrays.asList(
new Person("John", 25),
new Person("Alice", 30),
new Person("Bob", 22),
new Person("Diana", 28)
);
Collections.sort(people);
System.out.println("People sorted by name (natural order):");
people.forEach(System.out::println);
// Employee - natural ordering by age
List<Employee> employees = Arrays.asList(
new Employee("John", 25, 50000),
new Employee("Alice", 30, 60000),
new Employee("Bob", 22, 45000),
new Employee("Diana", 28, 55000)
);
Collections.sort(employees);
System.out.println("\nEmployees sorted by age (natural order):");
employees.forEach(System.out::println);
// Product - natural ordering by category then name
List<Product> products = Arrays.asList(
new Product("Electronics", "Laptop", 999.99),
new Product("Furniture", "Chair", 149.99),
new Product("Electronics", "Mouse", 25.99),
new Product("Furniture", "Desk", 199.99),
new Product("Books", "Novel", 15.99)
);
Collections.sort(products);
System.out.println("\nProducts sorted by category then name (natural order):");
products.forEach(System.out::println);
}
}

Output:

People sorted by name (natural order):
Person{name='Alice   ', age=30}
Person{name='Bob     ', age=22}
Person{name='Diana   ', age=28}
Person{name='John    ', age=25}
Employees sorted by age (natural order):
Employee{name='Bob   ', age=22, salary=$45000.00}
Employee{name='John  ', age=25, salary=$50000.00}
Employee{name='Diana ', age=28, salary=$55000.00}
Employee{name='Alice ', age=30, salary=$60000.00}
Products sorted by category then name (natural order):
Product{category='Books       ', name='Novel     ', price=$ 15.99}
Product{category='Electronics ', name='Laptop    ', price=$999.99}
Product{category='Electronics ', name='Mouse     ', price=$ 25.99}
Product{category='Furniture   ', name='Chair     ', price=$149.99}
Product{category='Furniture   ', name='Desk      ', price=$199.99}

Using with Collections

With TreeSet:

import java.util.*;
class ComparableStudent implements Comparable<ComparableStudent> {
private int rollNumber;
private String name;
private double marks;
public ComparableStudent(int rollNumber, String name, double marks) {
this.rollNumber = rollNumber;
this.name = name;
this.marks = marks;
}
// Natural ordering by roll number
@Override
public int compareTo(ComparableStudent other) {
return Integer.compare(this.rollNumber, other.rollNumber);
}
@Override
public String toString() {
return String.format("Student{roll=%d, name='%-8s', marks=%.2f}", 
rollNumber, name, marks);
}
// Important: Consistent equals and hashCode
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ComparableStudent)) return false;
ComparableStudent that = (ComparableStudent) o;
return rollNumber == that.rollNumber;
}
@Override
public int hashCode() {
return Objects.hash(rollNumber);
}
}
public class TreeSetWithComparable {
public static void main(String[] args) {
TreeSet<ComparableStudent> studentSet = new TreeSet<>();
studentSet.add(new ComparableStudent(103, "Alice", 85.5));
studentSet.add(new ComparableStudent(101, "Bob", 78.0));
studentSet.add(new ComparableStudent(102, "Charlie", 92.5));
studentSet.add(new ComparableStudent(100, "Diana", 88.0));
System.out.println("Students in TreeSet (sorted by roll number):");
studentSet.forEach(System.out::println);
// Navigation methods work with Comparable
ComparableStudent first = studentSet.first();
ComparableStudent last = studentSet.last();
System.out.println("\nFirst student: " + first);
System.out.println("Last student: " + last);
// Find student with roll number >= 102
ComparableStudent searchKey = new ComparableStudent(102, "", 0);
ComparableStudent result = studentSet.ceiling(searchKey);
System.out.println("Student with roll >= 102: " + result);
}
}

Output:

Students in TreeSet (sorted by roll number):
Student{roll=100, name='Diana   ', marks=88.00}
Student{roll=101, name='Bob     ', marks=78.00}
Student{roll=102, name='Charlie ', marks=92.50}
Student{roll=103, name='Alice   ', marks=85.50}
First student: Student{roll=100, name='Diana   ', marks=88.00}
Last student: Student{roll=103, name='Alice   ', marks=85.50}
Student with roll >= 102: Student{roll=102, name='Charlie ', marks=92.50}

With TreeMap:

import java.util.*;
class Account implements Comparable<Account> {
private String accountNumber;
private String holderName;
private double balance;
public Account(String accountNumber, String holderName, double balance) {
this.accountNumber = accountNumber;
this.holderName = holderName;
this.balance = balance;
}
// Natural ordering by account number
@Override
public int compareTo(Account other) {
return this.accountNumber.compareTo(other.accountNumber);
}
@Override
public String toString() {
return String.format("Account{number='%s', holder='%-8s', balance=$%.2f}", 
accountNumber, holderName, balance);
}
}
public class TreeMapWithComparable {
public static void main(String[] args) {
TreeMap<Account, String> accountMap = new TreeMap<>();
Account acc1 = new Account("ACC1001", "Alice", 1500.0);
Account acc2 = new Account("ACC1003", "Bob", 2500.0);
Account acc3 = new Account("ACC1002", "Charlie", 1800.0);
accountMap.put(acc1, "Active");
accountMap.put(acc2, "Active");
accountMap.put(acc3, "Inactive");
System.out.println("Accounts in TreeMap (sorted by account number):");
accountMap.forEach((account, status) -> 
System.out.println(account + " -> " + status));
// Range queries work with Comparable
Account from = new Account("ACC1002", "", 0);
Account to = new Account("ACC1003", "", 0);
System.out.println("\nAccounts between ACC1002 and ACC1003:");
accountMap.subMap(from, true, to, true)
.forEach((acc, status) -> 
System.out.println(acc + " -> " + status));
}
}

Output:

Accounts in TreeMap (sorted by account number):
Account{number='ACC1001', holder='Alice   ', balance=$1500.00} -> Active
Account{number='ACC1002', holder='Charlie ', balance=$1800.00} -> Inactive
Account{number='ACC1003', holder='Bob     ', balance=$2500.00} -> Active
Accounts between ACC1002 and ACC1003:
Account{number='ACC1002', holder='Charlie ', balance=$1800.00} -> Inactive
Account{number='ACC1003', holder='Bob     ', balance=$2500.00} -> Active

Best Practices

1. Consistent with equals():

class ConsistentStudent implements Comparable<ConsistentStudent> {
private int id;
private String name;
public ConsistentStudent(int id, String name) {
this.id = id;
this.name = name;
}
// compareTo consistent with equals
@Override
public int compareTo(ConsistentStudent other) {
return Integer.compare(this.id, other.id);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ConsistentStudent)) return false;
ConsistentStudent that = (ConsistentStudent) o;
return id == that.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

2. Handle Null Values:

class NullSafeStudent implements Comparable<NullSafeStudent> {
private String name;
private Integer age; // Use Integer instead of int to handle null
public NullSafeStudent(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(NullSafeStudent other) {
// Handle null names
if (this.name == null && other.name == null) return 0;
if (this.name == null) return -1;
if (other.name == null) return 1;
int nameCompare = this.name.compareTo(other.name);
if (nameCompare != 0) return nameCompare;
// Handle null ages using Comparator
return Comparator.nullsFirst(Integer::compare)
.compare(this.age, other.age);
}
}

3. Use Integer.compare() and Double.compare():

class ProperComparison implements Comparable<ProperComparison> {
private int intValue;
private double doubleValue;
public ProperComparison(int intValue, double doubleValue) {
this.intValue = intValue;
this.doubleValue = doubleValue;
}
@Override
public int compareTo(ProperComparison other) {
// ❌ Bad - can cause integer overflow
// return this.intValue - other.intValue;
// ✅ Good - handles all cases properly
int intCompare = Integer.compare(this.intValue, other.intValue);
if (intCompare != 0) return intCompare;
return Double.compare(this.doubleValue, other.doubleValue);
}
}

Common Examples

1. Date/Time Ordering:

import java.time.LocalDate;
import java.util.*;
class Task implements Comparable<Task> {
private String name;
private LocalDate dueDate;
private Priority priority;
public Task(String name, LocalDate dueDate, Priority priority) {
this.name = name;
this.dueDate = dueDate;
this.priority = priority;
}
// Natural ordering: by due date (earliest first), then by priority
@Override
public int compareTo(Task other) {
int dateCompare = this.dueDate.compareTo(other.dueDate);
if (dateCompare != 0) {
return dateCompare;
}
return this.priority.compareTo(other.priority);
}
enum Priority {
LOW, MEDIUM, HIGH
}
@Override
public String toString() {
return String.format("Task{name='%-15s', dueDate=%-10s, priority=%-6s}", 
name, dueDate, priority);
}
}
public class TaskManager {
public static void main(String[] args) {
List<Task> tasks = Arrays.asList(
new Task("Write report", LocalDate.of(2024, 1, 15), Task.Priority.HIGH),
new Task("Meeting", LocalDate.of(2024, 1, 10), Task.Priority.MEDIUM),
new Task("Code review", LocalDate.of(2024, 1, 15), Task.Priority.LOW),
new Task("Design UI", LocalDate.of(2024, 1, 12), Task.Priority.HIGH),
new Task("Test features", LocalDate.of(2024, 1, 10), Task.Priority.HIGH)
);
Collections.sort(tasks);
System.out.println("Tasks sorted by due date then priority:");
tasks.forEach(System.out::println);
}
}

Output:

Tasks sorted by due date then priority:
Task{name='Meeting       ', dueDate=2024-01-10, priority=MEDIUM}
Task{name='Test features ', dueDate=2024-01-10, priority=HIGH  }
Task{name='Design UI     ', dueDate=2024-01-12, priority=HIGH  }
Task{name='Code review   ', dueDate=2024-01-15, priority=LOW   }
Task{name='Write report  ', dueDate=2024-01-15, priority=HIGH  }

2. Version Number Ordering:

import java.util.*;
class SoftwareVersion implements Comparable<SoftwareVersion> {
private int major;
private int minor;
private int patch;
public SoftwareVersion(int major, int minor, int patch) {
this.major = major;
this.minor = minor;
this.patch = patch;
}
// Natural ordering for version numbers: 1.2.3 < 1.3.0 < 2.0.0
@Override
public int compareTo(SoftwareVersion other) {
int majorCompare = Integer.compare(this.major, other.major);
if (majorCompare != 0) return majorCompare;
int minorCompare = Integer.compare(this.minor, other.minor);
if (minorCompare != 0) return minorCompare;
return Integer.compare(this.patch, other.patch);
}
@Override
public String toString() {
return String.format("v%d.%d.%d", major, minor, patch);
}
}
public class VersionManagement {
public static void main(String[] args) {
List<SoftwareVersion> versions = Arrays.asList(
new SoftwareVersion(2, 1, 0),
new SoftwareVersion(1, 0, 0),
new SoftwareVersion(1, 2, 3),
new SoftwareVersion(2, 0, 1),
new SoftwareVersion(1, 2, 0),
new SoftwareVersion(2, 0, 0)
);
Collections.sort(versions);
System.out.println("Software versions in natural order:");
versions.forEach(System.out::println);
// Using with TreeSet
TreeSet<SoftwareVersion> versionSet = new TreeSet<>(versions);
System.out.println("\nLatest version: " + versionSet.last());
System.out.println("Earliest version: " + versionSet.first());
}
}

Output:

Software versions in natural order:
v1.0.0
v1.2.0
v1.2.3
v2.0.0
v2.0.1
v2.1.0
Latest version: v2.1.0
Earliest version: v1.0.0

Advanced Topics

1. Reverse Natural Ordering:

import java.util.*;
class ReverseComparable<T extends Comparable<T>> implements Comparable<ReverseComparable<T>> {
private T value;
public ReverseComparable(T value) {
this.value = value;
}
public T getValue() { return value; }
@Override
public int compareTo(ReverseComparable<T> other) {
// Reverse the natural ordering
return other.value.compareTo(this.value);
}
@Override
public String toString() {
return value.toString();
}
}
public class ReverseNaturalOrder {
public static void main(String[] args) {
List<ReverseComparable<String>> names = Arrays.asList(
new ReverseComparable<>("Alice"),
new ReverseComparable<>("Bob"),
new ReverseComparable<>("Charlie"),
new ReverseComparable<>("Diana")
);
Collections.sort(names);
System.out.println("Names in reverse natural order:");
names.forEach(System.out::println);
}
}

2. Generic Comparable Implementation:

import java.util.*;
class GenericEntity<T extends Comparable<T>> implements Comparable<GenericEntity<T>> {
private T id;
private String name;
public GenericEntity(T id, String name) {
this.id = id;
this.name = name;
}
@Override
public int compareTo(GenericEntity<T> other) {
return this.id.compareTo(other.id);
}
@Override
public String toString() {
return String.format("Entity{id=%s, name='%s'}", id, name);
}
}
public class GenericComparable {
public static void main(String[] args) {
// Using with Integer ID
List<GenericEntity<Integer>> intEntities = Arrays.asList(
new GenericEntity<>(3, "Third"),
new GenericEntity<>(1, "First"),
new GenericEntity<>(2, "Second")
);
Collections.sort(intEntities);
System.out.println("Entities with Integer IDs:");
intEntities.forEach(System.out::println);
// Using with String ID
List<GenericEntity<String>> stringEntities = Arrays.asList(
new GenericEntity<>("C", "Third"),
new GenericEntity<>("A", "First"),
new GenericEntity<>("B", "Second")
);
Collections.sort(stringEntities);
System.out.println("\nEntities with String IDs:");
stringEntities.forEach(System.out::println);
}
}

Complete Examples

Complete Working Example:

import java.util.*;
public class ComparableCompleteExample {
public static void main(String[] args) {
System.out.println("=== Comparable Interface Complete Example ===\n");
// Example 1: Basic Student Comparison
basicStudentComparison();
// Example 2: Complex Multi-field Comparison
complexMultiFieldComparison();
// Example 3: Real-world Use Case - Employee Management
employeeManagementExample();
// Example 4: Advanced - Custom Sorting Logic
customSortingLogic();
}
public static void basicStudentComparison() {
System.out.println("1. Basic Student Comparison:");
List<BasicStudent> students = Arrays.asList(
new BasicStudent(103, "Alice", 85.5),
new BasicStudent(101, "Bob", 78.0),
new BasicStudent(102, "Charlie", 92.5),
new BasicStudent(100, "Diana", 88.0)
);
Collections.sort(students);
System.out.println("Students sorted by roll number (natural order):");
students.forEach(System.out::println);
System.out.println();
}
public static void complexMultiFieldComparison() {
System.out.println("2. Complex Multi-field Comparison:");
List<ComplexProduct> products = Arrays.asList(
new ComplexProduct("Electronics", "Laptop", 999.99, 4.5),
new ComplexProduct("Furniture", "Chair", 149.99, 4.2),
new ComplexProduct("Electronics", "Mouse", 25.99, 4.7),
new ComplexProduct("Books", "Novel", 15.99, 4.8),
new ComplexProduct("Electronics", "Laptop", 899.99, 4.3)
);
Collections.sort(products);
System.out.println("Products sorted by category → name → price (natural order):");
products.forEach(System.out::println);
System.out.println();
}
public static void employeeManagementExample() {
System.out.println("3. Employee Management Example:");
TreeSet<Employee> employees = new TreeSet<>();
employees.add(new Employee("John", "Developer", 3, 60000));
employees.add(new Employee("Alice", "Manager", 5, 75000));
employees.add(new Employee("Bob", "Developer", 2, 55000));
employees.add(new Employee("Diana", "Designer", 4, 65000));
employees.add(new Employee("Charlie", "Developer", 3, 62000));
System.out.println("Employees sorted by experience then salary:");
employees.forEach(System.out::println);
// Find employees with experience >= 3 years
Employee searchKey = new Employee("", "", 3, 0);
SortedSet<Employee> experienced = employees.tailSet(searchKey);
System.out.println("\nEmployees with 3+ years experience:");
experienced.forEach(System.out::println);
System.out.println();
}
public static void customSortingLogic() {
System.out.println("4. Custom Sorting Logic - Case Insensitive:");
List<CaseInsensitiveString> words = Arrays.asList(
new CaseInsensitiveString("Apple"),
new CaseInsensitiveString("banana"),
new CaseInsensitiveString("Cherry"),
new CaseInsensitiveString("date"),
new CaseInsensitiveString("Elderberry")
);
Collections.sort(words);
System.out.println("Words sorted case-insensitively:");
words.forEach(System.out::println);
}
}
// Supporting classes
class BasicStudent implements Comparable<BasicStudent> {
private int rollNumber;
private String name;
private double marks;
public BasicStudent(int rollNumber, String name, double marks) {
this.rollNumber = rollNumber;
this.name = name;
this.marks = marks;
}
@Override
public int compareTo(BasicStudent other) {
return Integer.compare(this.rollNumber, other.rollNumber);
}
@Override
public String toString() {
return String.format("Student{roll=%d, name='%-8s', marks=%.2f}", 
rollNumber, name, marks);
}
}
class ComplexProduct implements Comparable<ComplexProduct> {
private String category;
private String name;
private double price;
private double rating;
public ComplexProduct(String category, String name, double price, double rating) {
this.category = category;
this.name = name;
this.price = price;
this.rating = rating;
}
@Override
public int compareTo(ComplexProduct other) {
// Primary: category
int categoryCompare = this.category.compareTo(other.category);
if (categoryCompare != 0) return categoryCompare;
// Secondary: name
int nameCompare = this.name.compareTo(other.name);
if (nameCompare != 0) return nameCompare;
// Tertiary: price (lower price first)
return Double.compare(this.price, other.price);
}
@Override
public String toString() {
return String.format("Product{category='%-12s', name='%-10s', price=$%6.2f, rating=%.1f}", 
category, name, price, rating);
}
}
class Employee implements Comparable<Employee> {
private String name;
private String department;
private int yearsExperience;
private double salary;
public Employee(String name, String department, int yearsExperience, double salary) {
this.name = name;
this.department = department;
this.yearsExperience = yearsExperience;
this.salary = salary;
}
@Override
public int compareTo(Employee other) {
// Primary: years of experience (more experience first)
int expCompare = Integer.compare(other.yearsExperience, this.yearsExperience);
if (expCompare != 0) return expCompare;
// Secondary: salary (higher salary first)
return Double.compare(other.salary, this.salary);
}
@Override
public String toString() {
return String.format("Employee{name='%-8s', dept='%-10s', exp=%d years, salary=$%7.2f}", 
name, department, yearsExperience, salary);
}
}
class CaseInsensitiveString implements Comparable<CaseInsensitiveString> {
private String value;
public CaseInsensitiveString(String value) {
this.value = value;
}
@Override
public int compareTo(CaseInsensitiveString other) {
return this.value.compareToIgnoreCase(other.value);
}
@Override
public String toString() {
return value;
}
}

Expected Output:

=== Comparable Interface Complete Example ===
1. Basic Student Comparison:
Students sorted by roll number (natural order):
Student{roll=100, name='Diana   ', marks=88.00}
Student{roll=101, name='Bob     ', marks=78.00}
Student{roll=102, name='Charlie ', marks=92.50}
Student{roll=103, name='Alice   ', marks=85.50}
2. Complex Multi-field Comparison:
Products sorted by category → name → price (natural order):
Product{category='Books       ', name='Novel     ', price=$ 15.99, rating=4.8}
Product{category='Electronics ', name='Laptop    ', price=$899.99, rating=4.3}
Product{category='Electronics ', name='Laptop    ', price=$999.99, rating=4.5}
Product{category='Electronics ', name='Mouse     ', price=$ 25.99, rating=4.7}
Product{category='Furniture   ', name='Chair     ', price=$149.99, rating=4.2}
3. Employee Management Example:
Employees sorted by experience then salary:
Employee{name='Alice   ', dept='Manager   ', exp=5 years, salary=$75000.00}
Employee{name='Diana   ', dept='Designer  ', exp=4 years, salary=$65000.00}
Employee{name='Charlie ', dept='Developer ', exp=3 years, salary=$62000.00}
Employee{name='John    ', dept='Developer ', exp=3 years, salary=$60000.00}
Employee{name='Bob     ', dept='Developer ', exp=2 years, salary=$55000.00}
Employees with 3+ years experience:
Employee{name='Alice   ', dept='Manager   ', exp=5 years, salary=$75000.00}
Employee{name='Diana   ', dept='Designer  ', exp=4 years, salary=$65000.00}
Employee{name='Charlie ', dept='Developer ', exp=3 years, salary=$62000.00}
Employee{name='John    ', dept='Developer ', exp=3 years, salary=$60000.00}
4. Custom Sorting Logic - Case Insensitive:
Words sorted case-insensitively:
Apple
banana
Cherry
date
Elderberry

Key Takeaways

  1. Comparable defines natural ordering - the default way objects should be sorted
  2. Single method - compareTo(T o) returns negative, zero, or positive
  3. Used by Java Collections - TreeSet, TreeMap, Collections.sort()
  4. Consistent with equals() - should maintain compareTo == 0equals()
  5. Handle edge cases - null values, integer overflow, multi-field comparison
  6. Use helper methods - Integer.compare(), Double.compare(), Comparator.nullsFirst()
  7. Perfect for default sorting - when objects have one obvious natural order

The Comparable interface is fundamental for creating sortable objects in Java and is essential for working with sorted collections and algorithms.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper