Table of contents
1.
Introduction
2.
Java Comparable interface
3.
compareTo(Object obj) method
4.
Collections class
5.
Method of Collections class for sorting List elements
5.1.
1. sort(List<T> list)
5.2.
2. sort(List<T> list, Comparator<? super T> c)
6.
Java Comparable Example
7.
Java Comparable Example: Reverse Order
8.
Frequently Asked Questions
8.1.
Can we sort objects of a class that doesn't implement the Comparable interface?
8.2.
What happens if the compareTo() method returns 0?
8.3.
Can we sort objects in descending order without using Collections.reverseOrder()?
9.
Conclusion
Last Updated: Nov 4, 2024
Easy

Comparable Interface in Java

Author Rinki Deka
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In Java, sorting objects of a class is a basic task that can be accomplished using the Comparable interface. This interface is part of the java.lang package & provides a way to define the natural ordering of objects within a class. With the implementation of a Comparable interface, you can enable objects to be compared & sorted based on their natural order. The interface declares a single method, which is known as compareTo(), which takes an object as a parameter & returns an integer value that indicates whether the current object is less than, equal to, or greater than the compared object. The Collections class in Java offers many sorting methods that rely on the Comparable interface to sort objects in ascending or descending order. 

Comparable Interface in Java

In this article, we will look into the Comparable interface, discuss its compareTo() method, & show how to utilize it with Collections class to sort objects efficiently.

Java Comparable interface

The Comparable interface in Java is defined in the java.lang package. It is a generic interface that takes a type parameter T, representing the type of objects that can be compared. The interface declares a single method named compareTo(), which compares the current object with another object of the same type.

The declaration of the Comparable interface is:

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


To use the Comparable interface, a class must implement it and provide an implementation for the compareTo() method. The compareTo() method should define the natural ordering of objects within the class. It compares the current object with the specified object and returns an integer value based on the comparison result.

The Comparable interface is commonly used with classes that have a natural ordering, such as numerical values, strings, or dates. By implementing the Comparable interface, you enable objects of a class to be sorted and compared based on their natural order.

When we implement the Comparable interface provides many benefits:

1. It allows objects to be sorted using various sorting algorithms provided by the Collections class or Arrays class.
 

2. It enables objects to be used in sorted collections, such as TreeSet or TreeMap, which maintain elements in sorted order.
 

3. It provides a standardized way to compare objects of a class, making the code more readable & maintainable.

compareTo(Object obj) method

The compareTo(Object obj) method is the sole method declared in the Comparable interface. It compares the current object with the specified object and determines its relative order. The method takes an object of the same type as a parameter and returns an integer value indicating the comparison result.

The compareTo() method should return:

  • A negative integer if the current object is considered less than the specified object.
     
  • Zero if the current object is considered equal to the specified object.
     
  • A positive integer if the current object is considered greater than the specified object.


The general syntax of the compareTo() method is:

public int compareTo(T obj) {
    // Comparison logic goes here
}


When implementing the compareTo() method, you must define the comparison logic based on the specific attributes or properties of the objects being compared. The comparison can be based on a single attribute or a combination of attributes, depending on the desired natural ordering.

For example, let's consider a Person class with attributes like name & age. To compare Person objects based on their age, you can implement the compareTo() method as mentioned below:

public class Person implements Comparable<Person> {
    private String name;
    private int age;
    
    // Constructor, getters, and setters
    
    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);
    }
}


In this example, the compareTo() method compares the age attribute of the current Person object with the age attribute of the specified Person object using the Integer.compare() method. The Integer.compare() method returns a negative value if the first argument is less than the second, zero if they are equal, & a positive value if the first argument is greater than the second.

Implementing the compareTo() method in this way allows person objects to be sorted in ascending order based on their age. Sorting methods and sorted collections will use the natural ordering defined by the compareTo() method.

It's important to ensure that the compareTo() method provides a consistent ordering. It should be reflexive, symmetric, & transitive. In other words, the following conditions should be fulfilled:

  • Reflexive: compareTo(x, x) should return 0.
     
  • Symmetric: if compareTo(x, y) returns a negative value, compareTo(y, x) should return a positive value.
     
  • Transitive: if compareTo(x, y) < 0 & compareTo(y, z) < 0, then compareTo(x, z) should be < 0.

Collections class

The Collections class is a utility class in Java that provides various static methods for working with collections, like lists, sets, and maps. It offers various functionalities, like sorting, searching, shuffling, and synchronizing collection elements.


One of the main features of the Collections class is its ability to sort elements in a collection based on their natural ordering or a custom ordering defined by a Comparator. When sorting elements that implement the Comparable interface, the Collections class relies on the compareTo() method to determine the order of the elements.

 

Some commonly used methods of the Collections class related to sorting are:
 

1. sort(List<T> list): This method sorts the elements in the specified list in ascending order based on their natural ordering. The elements in the list must implement the Comparable interface.
 

2. sort(List<T> list, Comparator<? super T> c): This method sorts the elements in the specified list based on the order induced by the specified Comparator. It allows you to provide a custom ordering logic through a Comparator object.
 

3. reverseOrder(): This method returns a Comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface.
 

4. reverseOrder(Comparator<T> cmp): This method returns a Comparator that imposes the reverse ordering of the specified Comparator.
 

5. binarySearch(List<? extends Comparable<? super T>> list, T key): This method searches for the specified object in the specified list using the binary search algorithm. The list must be sorted in ascending order according to the natural ordering of its elements.
 

6. binarySearch(List<? extends T> list, T key, Comparator<? super T> c): This method searches for the specified object in the specified list using the binary search algorithm. The list must be sorted in ascending order according to the specified Comparator.

Method of Collections class for sorting List elements

The Collections class provides several methods for sorting elements in a List. The two most commonly used methods for sorting List elements are:

1. sort(List<T> list)

The sort(List<T> list) method is used to sort the elements of a List in ascending order based on their natural ordering. The elements in the list must implement the Comparable interface, which defines the natural ordering through the compareTo() method.

An example of using the sort() method to sort a List of integers:

List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);

System.out.println("Before sorting: " + numbers);
Collections.sort(numbers);
System.out.println("After sorting: " + numbers);


Output:

Before sorting: [5, 2, 8, 1]
After sorting: [1, 2, 5, 8]


In this example, the List of integers is sorted in ascending order using the natural ordering of integers.

2. sort(List<T> list, Comparator<? super T> c)

The sort(List<T> list, Comparator<? super T> c) method is used to sort the elements of a List based on a custom ordering defined by a Comparator. The Comparator interface provides a compare() method that determines the order of two elements.

This is an example of using the sort() method with a custom Comparator to sort a List of strings based on their length:

List<String> names = new ArrayList<>();
names.add("Ravi");
names.add("Rahul");
names.add("Dev");
names.add("Anish");


System.out.println("Before sorting: " + names);
Collections.sort(names, Comparator.comparingInt(String::length));
System.out.println("After sorting: " + names);


Output:

Before sorting: [Ravi, Rahul, Dev, Anish]
After sorting: [Dev, Ravi, Anish, Rahul]

 

In this example, the List of strings is sorted based on the length of each string. The Comparator.comparingInt(String::length) creates a Comparator that compares strings based on their length.

Java Comparable Example

Let's consider an example that shows the use of the Comparable interface and the Collections class for sorting objects. We'll create a Student class that implements the Comparable interface and defines the natural ordering based on the student's grade.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student implements Comparable<Student> {
    private String name;
    private int grade;


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


    public String getName() {
        return name;
    }


    public int getGrade() {
        return grade;
    }


    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.grade, other.grade);
    }


    @Override
    public String toString() {
        return name + " (Grade: " + grade + ")";
    }
}
public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ravi", 85));
        students.add(new Student("Rahul", 92));
        students.add(new Student("Dev", 78));
        students.add(new Student("Anish", 89));


        System.out.println("Before sorting:");
        for (Student student : students) {
            System.out.println(student);
        }

        Collections.sort(students);

        System.out.println("\nAfter sorting:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

Before sorting:
Ravi (Grade: 85)
Rahul (Grade: 92)
Dev (Grade: 78)
Anish (Grade: 89)

After sorting:
Dev (Grade: 78)
Ravi (Grade: 85)
Anish (Grade: 89)
Rahul (Grade: 92)


In this example, we have a Student class that implements the Comparable interface. The compareTo() method is overridden to compare students based on their grade using Integer.compare().


In the Main class, we create a List of Student objects & add some sample data. We print the list before sorting to see the initial order of the students.


Then, we use Collections.sort(students) to sort the list of students based on their natural ordering defined by the compareTo() method. The students are sorted in ascending order of their grade.

Finally, we print the sorted list of students to see the result.


This example shows how the Comparable interface and the Collections class can be used together to sort objects based on their natural ordering. By implementing the compareTo() method in the Student class, we define the natural ordering of students based on their grades, and the Collections.sort() method uses that ordering to sort the list.

Note: Depending on your requirements, you can modify the compareTo() method to define the natural ordering based on different attributes or a combination of attributes.

Java Comparable Example: Reverse Order

In the previous example, we saw how to sort objects in ascending order based on their natural ordering using the Comparable interface & the Collections class. Now, let's explore how to sort objects in reverse order.

To sort objects in reverse order, you can use the Collections.reverseOrder() method, which returns a Comparator that imposes the reverse of the natural ordering. 

Let’s see an example that demonstrates sorting students in reverse order based on their grade:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


class Student implements Comparable<Student> {
    // Same Student class implementation as before
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Ravi", 85));
        students.add(new Student("Rahul", 92));
        students.add(new Student("Dev", 78));
        students.add(new Student("Anish", 89));


        System.out.println("Before sorting:");
        for (Student student : students) {
            System.out.println(student);
        }

        Collections.sort(students, Collections.reverseOrder());

        System.out.println("\nAfter sorting in reverse order:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Before sorting:
Ravi (Grade: 85)
Rahul (Grade: 92)
Dev (Grade: 78)
Anish (Grade: 89)
After sorting in reverse order:
Rahul (Grade: 92)
Anish (Grade: 89)
Ravi (Grade: 85)
Dev (Grade: 78)


In this example, we use Collections.sort(students, Collections.reverseOrder()) to sort the list of students in reverse order. The Collections.reverseOrder() method returns a Comparator that reverses the natural ordering of the objects.

As a result, the students are sorted in descending order of their grade. The student with the highest grade appears first, followed by the second highest, and so on.

You can also use the Collections.sort(students, Comparator.reverseOrder()) method, which is equivalent to Collections.sort(students, Collections.reverseOrder()). Both methods achieve the same result of sorting the objects in reverse order.

Frequently Asked Questions

Can we sort objects of a class that doesn't implement the Comparable interface?

Yes, you can sort objects of a class that doesn't implement the Comparable interface by providing a custom Comparator to the Collections.sort() method.

What happens if the compareTo() method returns 0?

If the compareTo() method returns 0, it means that the current object is considered equal to the object being compared. In this case, the relative order of the objects remains unchanged.

Can we sort objects in descending order without using Collections.reverseOrder()?

Yes, you can sort objects in descending order by modifying the compareTo() method to return the opposite result. For example, instead of returning Integer.compare(this.grade, other.grade), you can return Integer.compare(other.grade, this.grade).

Conclusion

In this article, we learned about the Comparable interface in Java & how it can be used to define the natural ordering of objects within a class. We explained the compareTo() method, which is used to compare objects & determine their relative order. We also looked at the Collections class & its methods for sorting List elements based on their natural ordering or a custom order defined by a Comparator. With the help of the examples, we saw how to sort objects in ascending & descending order using the Comparable interface & the Collections class.
You can also check out our other blogs on Code360.

Live masterclass