Updated December 29, 2023
Table of Content
- Introduction
- Working of Comparable in Java with Example
- Methods of Java Comparable
- How Comparable Works in Java?
- Implement Comparable in Java
- Comparable vs Comparator
- Collection Interface in Java
Introduction
Comparable is an interface that compares current objects with others of the same type, allowing elements within a collection to be sorted. To make a class sortable or “comparable,” one must implement the Comparable interface and define the “compareTo” method. This process establishes natural ordering, and the implemented “compareTo” method serves as the natural comparison method for the type. Here in this Comparable in Java Example article, we will look at the different comparable examples in java.
Working of Comparable in Java with Example
The working of comparable in java is as follows:
Declaration:
Interface Comparable<T>
To implement this interface, you must implement this method:
public int compareTo(To);
Parameters:
T – is the type of object with which this object is compared to.
Return value:
compareTo method returns 0 if the object specified, and this object is equal. It returns a negative integer if this object is less than the object specified. It returns a positive integer if this object is greater than the specified object.
Throws:
- ClassCastException : It occurs if the object passed to this method is null.
- NullPointerException : It is thrown if the object passed to this method is incompatible with the current object.
Classes that implement a Comparable interface have their natural ordering specified with them, and so they can be sorted directly in Collection or Arrays using Collections.sort() and Arrays.sort(). You can also use them as keys in sorted maps and elements in sorted sets without specifying the comparison separately.
Let’s understand the Comparable interface with the help of an example:
Example #1
package comparableDemo;
import java.util.TreeSet;
public class Student implements Comparable<Student> {
private int rollNo;
private String name;
private int age;
public Student(int rollNo, String name, int age) {
this.rollNo = rollNo;
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
if (this.rollNo > o.rollNo) {
return 1;
} else if (this.rollNo == o.rollNo) {
return 0;
} else {
return -1;
}
}
@Override
public String toString() {
return "RollNo-" + this.rollNo + ", Name-" + this.name + ", Age-" + this.age;
}
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<>();
Student student1 = new Student(3, "Raj", 20);
Student student2 = new Student(5, "Shyam", 18);
Student student3 = new Student(1, "Ram", 19);
Student student4 = new Student(4, "Sunil", 25);
Student student5 = new Student(2, "Ajay", 26);
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
for (Student student : students) {
System.out.println(student);
}
}
}
Output:
Explanation
This is an application to store student details.
- First, we have created a class “Student” as the representation of the entity Student. Then, we are going to store basic details like roll number, name, and age of students.
- And the requirement is to sort the list of students based on roll number.
- To meet this requirement, the implementation incorporates the Comparable interface, and it compares the students based on roll number, as evident from the “compareTo” method.
- Then we have the main method to show the functionality. Here we have created a “TreeSet” and added five students with random roll numbers. We have used “TreeSet” because it stores elements in sorted order.
- Now, if you iterate through the list of students, you will find that students are sorted based on roll number. So that’s what our requirement was!
- We could also sort the students based on other attributes like name or age. To do this, we will have to use name or age variables in the “compareTo” method instead of “rollNo.”
Example #2
@Override
public int compareTo(Student o) {
if (this.age> o.age) {
return 1;
} else if (this.age == o.age) {
return 0;
} else {
return -1;
}
}
OR
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
Methods of Java Comparable
As already discussed, the following is the one and only method compareTo(obj) for the interface comparable.
compareTo(obj)
This method compares the object with the object obj for the order specified in it. In the practical scenario, this method will be overridden in order to return values. The return values of this method can be:
- +ve : In the case where the present object is greater than the object mentioned.
- -ve : In the case where the present object is less than the object mentioned.
- 0: In the case where the present object is equal to the object mentioned.
Syntax:
Below is the syntax of the comparable interface.
class Employee implements Comparable<Employee>
{
. . .
}
//compareTo method that has to be overridden
public int compareTo(Employee em)
{
. .
}
How Comparable Works in Java?
Suppose there is a group of students S1, S2, S3, S4 where their heights are 145, 187, 166, 172 and age is 23, 24, 21, 26. In what ways we can sort them? Height, Weight, Age, etc., right?
- Even if we compare them based on one criteria, Age, we have to repeatedly compare and sort two students until all the students age are considered. That is, is student 1 age is greater than student 2, student 2 age greater than student 3 age etc. In order to accomplish this objective, a comparable interface came into action.
- The method compareTo() in comparable interface helps in achieving it. As already discussed, this method returns either a positive, negative or zero value. So, this object will be compared with the argument object on calling this method. If the age is lesser, then a negative value will be returned. Similarly, a positive value will be returned if the age is higher.
Implement Comparable in Java
Below are the examples to understand comparable interface with the help of programs.
Example #1
Java program to create a student list and sort the elements based on the height’s natural ordering.
Code:
//Driver class
import java.util.ArrayList;
import java.util.Collections;
// Driver class
class Main
{
//main method
public static void main(String[] args)
{
//create an array list
ArrayList<Student>li = new ArrayList<Student>();
//add elements to the array list
li.add(new Student("Kukku", 45 , 162));
li.add(new Student("Kunju", 43 , 164));
li.add(new Student("Anna" , 47 , 173));
li.add(new Student("Adam" , 49 , 181));
//sort the list
Collections.sort(li);
System.out.println("After sorting, student list will be : ");
//print elements in the list one by one
for (Student st: li)
{
System.out.println(st.getName() + " " + st.getMark() + " " + st.getHeight());
}
}
}
//Student class
// Student is a class that implements Comparable
class Student implements Comparable<Student>
{
private int mark;
private String name;
private int height;
// sort students based on mark
public int compareTo(Student s)
{
return this.height - s.height;
}
// Constructor of the class
public Student(String nam, int ag, int hght)
{
this.name = nam;
this.mark = ag;
this.height = hght;
}
// To access private methods, create get methods
public double getMark()
{
return mark;
}
public String getName()
{
return name;
}
public int getHeight()
{
return height;
}
}
Output:
Explanation:
The program first creates a student list and sorts its elements based on their height. To compare marks instead, one only needs to change the parameter inside the compareTo() method.
Example #2
Java program to create a student list and sort the elements based on reverse order of the height.
Code:
//Driver class
import java.util.ArrayList;
import java.util.Collections;
// Driver class
class Main
{
//main method
public static void main(String[] args)
{
//create an array list
ArrayList<Student>li = new ArrayList<Student>();
//add elements to the array list
li.add(new Student("Kukku", 45 , 162));
li.add(new Student("Kunju", 43 , 164));
li.add(new Student("Anna" , 47 , 173));
li.add(new Student("Adam" , 49 , 181));
//sort the list
Collections.sort(li, Collections.reverseOrder());
System.out.println("After sorting, student list will be : ");
//print elements in the list one by one
for (Student st: li)
{
System.out.println(st.getName() + " " + st.getMark() + " " + st.getHeight());
}
}
}
//Student class
// Student is a class that implements Comparable
class Student implements Comparable<Student>
{
private int mark;
private String name;
private int height;
// sort students based on mark
public int compareTo(Student s)
{
return this.height - s.height;
}
// Constructor of the class
public Student(String nam, int ag, int hght)
{
this.name = nam;
this.mark = ag;
this.height = hght;
}
// To access private methods, create get methods
public double getMark()
{
return mark;
}
public String getName()
{
return name;
}
public int getHeight()
{
return height;
}
}
Output:
Explanation:
In this program, similar to the first program, a student list is created first, and elements are sorted based on their height. The difference between the first example and this program is the ordering of the elements. In this program, the reverseOrder() method accomplishes reverse ordering, and then it prints the elements based on it.
Comparable vs Comparator
A comparator, like a Comparable, is an interface employed for comparing two objects of a type. However, unlike Comparable, the entity class itself does not implement Comparator. We must implement it in another class and provide the instance of it to the sorting mechanism explicitly. We can also use an anonymous class instance for this purpose.
For example, suppose we have a Student class without implementing a Comparable interface:
Code:
package comparableDemo;
import java.util.TreeSet;
public class Student{
private int rollNo;
private String name;
private int age;
public Student(int rollNo, String name, int age) {
this.rollNo = rollNo;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "RollNo-" + this.rollNo + ", Name-" + this.name + ", Age-" + this.age;
}
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<>();
Student student1 = new Student(3, "Raj", 20);
Student student2 = new Student(5, "Shyam", 18);
Student student3 = new Student(1, "Ram", 19);
Student student4 = new Student(4, "Sunil", 25);
Student student5 = new Student(2, "Ajay", 26);
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
for (Student student : students) {
System.out.println(student);
}
}
}
If you try to execute this program, you will get this exception:
Output:
Because TreeSet needs a way to sort the elements.
To resolve this error, we can use Comparator as implemented in this program:
Code:
package comparableDemo;
import java.util.Comparator;
import java.util.TreeSet;
public class Student {
private int rollNo;
private String name;
private int age;
public Student(int rollNo, String name, int age) {
this.rollNo = rollNo;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "RollNo-" + this.rollNo + ", Name-" + this.name + ", Age-" + this.age;
}
public static void main(String[] args) {
Comparator<Student> studentComparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if (o1.rollNo < o2.rollNo) {
return -1;
} else if (o1.rollNo == o2.rollNo) {
return 0;
} else {
return 1;
}
}
};
TreeSet<Student> students = new TreeSet<>(studentComparator);
Student student1 = new Student(3, "Raj", 20);
Student student2 = new Student(5, "Shyam", 18);
Student student3 = new Student(1, "Ram", 19);
Student student4 = new Student(4, "Sunil", 25);
Student student5 = new Student(2, "Ajay", 26);
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
for (Student student : students) {
System.out.println(student);
}
}
}
Output:
You can see that the Comparator interface is implemented in an anonymous inner class, and the instance is provided to TreeSet for sorting elements. Now you will get a proper output as earlier.
Collection Interface in Java
The collection is the root interface in the collections framework. It declares all general-purpose methods implemented in collections such as Lists and Sets. Map interface does not extend the Collection interface because Map is a collection of key-value pairs and not just a collection of elements. Some of the Collection interface methods are implemented in an abstract class, “AbstractCollection”.
Specific interfaces extend this interface because its implementation varies according to different collections. For example, some collections allow duplicate elements (Ex- List), some do not (Ex- Set), and some maintain indexing (Ex- List), whereas some do not (Ex- Set).
Some important methods are described here:
- Boolean add(E e): This method adds an element to this collection and returns the add operation status.
- boolean addAll(Collection<? extends E> c): This method adds all the elements from the specified collection into this collection and returns the add operation status.
- void clear(): This method removes all the elements from this collection.
- boolean contains(Object o): This method checks if the specified element is present in the collection or not. Returns true or false accordingly.
- boolean contains(Collection<?> c): This method checks if all the specified collection elements are present in this collection or not and returns true or false accordingly.
- boolean isEmpty(): This method checks if the collection is empty or not and returns true or false accordingly.
- Iterator<E> iterator(): This method returns an iterator for this collection. Iterator is used to iterate through all the elements in this collection.
- boolean remove(Object o): This method removes the specified element from the collection and returns the remove operation status.
- boolean removeAll(Collection<?> c): This method removes all the elements from this collection that are present in the specified collection and this collection.
- boolean retainAll(Collection<?> c): This method removes all the elements from this collection that are not present in the specified collection and present in this collection.
- int size(): This method returns the size of this collection.
- Object[] toArray(): This is an important method that forms and returns the array containing this collection’s elements.
- <T> T[] toArray(T[] a): This method adds all the elements of this collection into a specified array and returns the array. If the size of the array is less than the size of this collection, then it creates a new array of types that are the same as the type of the specified array and returns it. If the specified array size exceeds the size of this collection, the method sets null values for the remaining elements in the array and returns the array.
Conclusion
To summarize, the Comparable in Java interface is very useful for comparing objects manually, sort collections and arrays, or having a sorted collection itself. We can also sort elements based on different attributes of the entity. While not mandatory, it highly recommends maintaining consistent results between the equals and the “compareTo” method. This practice helps prevent confusion in a collection utilizing both of these methods.
Recommended Articles
We hope that this EDUCBA information on “Comparable in Java Example” was beneficial to you. You can view EDUCBA’s recommended articles for more information.