Comparable Interface in Java
The Comparable interface in Java is used to define the natural ordering of objects of a class. A class that implements Comparable tells Java how to decide whether one of its objects comes before or after another. Methods such as Collections.sort, Arrays.sort and classes such as TreeSet and TreeMap use this ordering automatically. String, Integer, LocalDate and most built-in value classes already implement it. In this lesson, you will learn how to implement Comparable in your own classes.
Declaration
public interface Comparable<T> {
int compareTo(T other);
}Comparable is in the java.lang package, so no import is needed. It has exactly one method, compareTo.
The compareTo Method
a.compareTo(b) must return:
| Return value | Meaning |
|---|---|
| A negative number | a comes before b |
| Zero | a and b are equal in order |
| A positive number | a comes after b |
Only the sign matters; -1 and -50 mean the same thing.
Why Use Comparable
Sorting a list of strings or numbers just works, because those classes know how to compare themselves. A class you write, such as Student, doesn't. Calling Collections.sort on a List<Student> without Comparable doesn't even compile, because Java has no idea which student should come first.
Example: Sorting Students by Marks
Let's see an example where students are naturally ordered by marks.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student implements Comparable<Student> {
String name;
int marks;
Student(String name, int marks) {
this.name = name;
this.marks = marks;
}
@Override
public int compareTo(Student other) {
return Integer.compare(this.marks, other.marks);
}
@Override
public String toString() {
return name + "(" + marks + ")";
}
}
public class StudentSort {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Navika", 91));
students.add(new Student("Srihitha", 78));
students.add(new Student("Advitha", 85));
Collections.sort(students);
System.out.println(students);
}
}[Srihitha(78), Advitha(85), Navika(91)]Explanation: Student implements Comparable<Student>, and compareTo compares marks with Integer.compare. Collections.sort calls compareTo to decide the order, so the students come out from the lowest to the highest marks.
Built-In Classes Already Comparable
public class BuiltIn {
public static void main(String[] args) {
System.out.println("Navika".compareTo("Advitha"));
System.out.println(Integer.valueOf(5).compareTo(9));
System.out.println("Navika".compareTo("Navika"));
}
}13
-1
0Explanation: "Navika" comes after "Advitha" alphabetically, so the result is positive (13 is the gap between the letters N and A). 5 comes before 9, so the result is negative. Equal strings give 0.
Rules for a Correct compareTo
- Opposite signs: if
a.compareTo(b)is negative,b.compareTo(a)must be positive. - Transitive: if
ais beforebandbis beforec, thenamust be beforec. - Consistent with equals (recommended):
compareToreturning 0 should meanequalsreturnstrue.TreeSettreats objects that compare as 0 as duplicates.
Common Mistakes
Subtracting numbers in compareTo. Use Integer.compare, Double.compare or Long.compare.
Forgetting the type argument: implements Comparable. Write Comparable<Student> so compareTo receives a Student, not an Object.
Adding two different students with the same marks to a TreeSet. If compareTo returns 0, the second one is dropped as a duplicate.
Interview Corner
What is the Comparable interface?
Comparable<T> in java.lang defines a class's natural ordering through one method, int compareTo(T o), which returns a negative number, zero or a positive number when the object is less than, equal to or greater than the argument. Sorting methods and sorted collections such as TreeSet and TreeMap use it automatically. A class can have only one natural order.
Practice
- Easy: Create a
Bookclass with a title and price, make itComparableby price, and sort a list of three books. - Harder: Make
Bookcompare by price and, when prices are equal, by title. Put books with equal prices into aTreeSetand check that none are lost.
Key Takeaways
Was this tutorial helpful?