Comparator interface vs Comparable interface
Comparator interface vs Comparable interface
Streams-api has many nice features that support sort by using Comparators on the fly.
In Java language, the Comparator interface makes use of default methods heavily. See https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
Let’s break down Comparable
and Comparator
. Both are Java interfaces used to define how objects of a particular class are ordered (sorted). The key difference lies in where the comparison logic resides and how flexible it is.
Comparable<T>
- Purpose: Defines the natural ordering for objects of a class. This is the single, most obvious way objects of this class should be sorted by default.
- Interface:
java.lang.Comparable<T>
- Method: Requires implementing a single method:
public int compareTo(T other)
- Implementation: The class whose instances need to be sorted must implement this interface itself.
- Logic: The
compareTo
method comparesthis
object with theother
object passed as an argument.- Returns a negative integer if
this
object comes beforeother
. - Returns zero if
this
object is equal toother
in terms of ordering. - Returns a positive integer if
this
object comes afterother
.
- Returns a negative integer if
- Use Case: Used by sorting methods like
Collections.sort(list)
andArrays.sort(array)
when no explicitComparator
is provided. Also used by sorted data structures likeTreeSet
andTreeMap
by default. - Flexibility: Limited. Only allows one sorting implementation directly within the class.
- Example Classes:
String
,Integer
,Double
,Date
all implementComparable
for their natural alphabetical/numerical/chronological order.
Comparator<T>
- Purpose: Defines custom or multiple alternative orderings for objects of a class. It decouples the comparison logic from the class being compared.
- Interface:
java.util.Comparator<T>
- Method: Requires implementing a single method:
public int compare(T o1, T o2)
(Note: takes two objects). - Implementation: A separate class implements this interface. This separate class defines how to compare two objects of type
T
. Often implemented using separate classes, anonymous inner classes, or lambda expressions (Java 8+). - Logic: The
compare
method compares the two objectso1
ando2
.- Returns a negative integer if
o1
comes beforeo2
. - Returns zero if
o1
is equal too2
in terms of this specific ordering. - Returns a positive integer if
o1
comes aftero2
.
- Returns a negative integer if
- Use Case: Used when:
- You need to sort objects based on different criteria (e.g., sort
Person
objects by name, then by age, then by ID). - You want to sort objects of a class you cannot modify (e.g., from a third-party library).
- You want to provide a specific order to methods like
Collections.sort(list, comparator)
orArrays.sort(array, comparator)
. - You want to create sorted data structures like
TreeSet
orTreeMap
with a custom order (new TreeSet<>(myComparator)
).
- You need to sort objects based on different criteria (e.g., sort
- Flexibility: High. Allows multiple, independent sorting strategies for a single class without modifying the class itself.
Analogy
Comparable
: Think of people having an inherent, natural way to compare themselves, like by height. Theheight
comparison logic is part of thePerson
class itself (compareTo
).Comparator
: Think of bringing in external judges. One judge compares people by weight (WeightComparator
), another by running speed (SpeedComparator
). These judges (Comparator
implementations) are separate from thePerson
class and provide different ways to order people.
Comparison Table
Feature | Comparable<T> |
Comparator<T> |
---|---|---|
Purpose | Natural, default ordering | Custom, multiple, external orderings |
Interface | java.lang.Comparable<T> |
java.util.Comparator<T> |
Key Method | int compareTo(T other) |
int compare(T o1, T o2) |
Implementation | Implemented by the class itself | Implemented by a separate class |
# Sort Logics | One per class | Many per class |
Modification | Requires modifying the class | Does not require modifying the class |
Default Sorting | Used by default (sort(list) ) |
Used when explicitly passed (sort(list, c) ) |
Package | java.lang |
java.util |
When to Use Which
- Use
Comparable
when there’s a clear, single, natural way to order objects of your class. Implement it directly in your class. - Use
Comparator
when:- You need multiple ways to sort objects.
- You need to sort objects of a class you cannot modify.
- You want to keep sorting logic separate from the domain object’s core responsibilities.
The Comparator interface is more flexible and provides more control over the sorting behavior of objects. If you need to sort objects based on different criteria or if the objects do not implement the Comparable interface, you should use the Comparator interface. On the other hand, if you want to define the natural ordering of an object, you should use the Comparable interface.