Skip to main content

Comparable vs Comparator

This document explains:

  • Why sorting requires comparison logic
  • What Comparable is
  • What Comparator is
  • Key differences
  • Internal usage in Collections & Tree structures
  • Contract rules
  • Common mistakes
  • Java 8 enhancements
  • Interview traps
  • Automation relevance
  • Code examples

1️⃣ Why Comparison Is Required

Sorting requires a rule to determine:

Which element is smaller?
Which element is greater?

Java provides two mechanisms:

✔ Comparable (natural ordering)
✔ Comparator (custom ordering)


2️⃣ Comparable Interface

Definition:

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

Rules:

• Implemented inside the class
• Defines natural ordering
• Only one compareTo allowed per class


3️⃣ compareTo() Return Rules

Return Value Meaning


< 0 this < other 0 equal > 0 this > other

Example:

class Student implements Comparable<Student> {
int id;

Student(int id) {
this.id = id;
}

@Override
public int compareTo(Student s) {
return this.id - s.id;
}

@Override
public String toString() {
return String.valueOf(id);
}
}

Usage:

List<Student> list = new ArrayList<>();
list.add(new Student(3));
list.add(new Student(1));

Collections.sort(list);
System.out.println(list); // [1, 3]

4️⃣ Comparator Interface

Definition:

public interface Comparator<T> {
int compare(T o1, T o2);
}

Rules:

• Defined outside the class
• Allows multiple sorting strategies
• More flexible


5️⃣ Comparator Example

class Student {
int id;
String name;

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

Comparator<Student> sortByName =
(s1, s2) -> s1.name.compareTo(s2.name);

List<Student> list = new ArrayList<>();
list.add(new Student(1, "B"));
list.add(new Student(2, "A"));

list.sort(sortByName);

6️⃣ Key Differences

Feature Comparable Comparator


Defined in Same class Separate class / Lambda Method compareTo() compare() Sorting type Natural Custom Multiple strategies ❌ ✅ Modification required Yes No


7️⃣ Internal Usage in Collections

Used by:

• TreeSet
• TreeMap
• PriorityQueue
• Collections.sort()
• Arrays.sort()

If no Comparator provided → uses Comparable.


8️⃣ Contract Rules

compareTo() must be:

✔ Consistent with equals()
✔ Transitive
✔ Anti-symmetric

If violated → unexpected behavior in TreeSet/TreeMap.

Example issue:

If compareTo returns 0 but equals false → duplicate elements may be lost.


9️⃣ Java 8 Enhancements

Comparator utility methods:

Comparator.comparing(Student::getName);
Comparator.comparingInt(Student::getId);
Comparator.reversed();
Comparator.thenComparing();

Example:

list.sort(
Comparator.comparing(Student::getName)
.thenComparing(Student::getId)
);

🔟 Reverse Sorting

Collections.sort(list, Comparator.reverseOrder());

Or:

list.sort(sortByName.reversed());

1️⃣1️⃣ Null Handling

Use:

Comparator.nullsFirst(...)
Comparator.nullsLast(...)

Example:

Comparator<String> comp =
Comparator.nullsFirst(String::compareTo);

1️⃣2️⃣ Common Mistakes

❌ Returning subtraction for large integers (overflow risk)

Better:

return Integer.compare(this.id, s.id);

❌ Inconsistent comparison logic
❌ Violating transitivity


1️⃣3️⃣ Interview Questions

Q: Can a class have multiple Comparable implementations? A: No.

Q: Which is better? A: Depends. Comparable for natural ordering; Comparator for flexibility.

Q: What happens if compareTo inconsistent with equals? A: TreeSet/TreeMap behave unpredictably.

Q: Which is used internally by TreeSet? A: Comparator if provided; else Comparable.


1️⃣4️⃣ Automation Framework Relevance

Useful for:

• Sorting API responses
• Sorting logs
• Custom report ordering
• Priority-based test execution
• Data validation before assertion

Example:

List<String> roles = Arrays.asList("USER", "ADMIN");
roles.sort(String::compareTo);

Final Mastery Checklist

You must understand:

✓ Natural vs Custom ordering
✓ compareTo contract
✓ Comparator flexibility
✓ Java 8 utilities
✓ TreeSet/TreeMap dependency
✓ Null handling
✓ Common pitfalls
✓ Automation use cases
✓ Interview clarity