Comparable and Comparator in Java
Table of contents
In Java, Comparable
and Comparator
are two interfaces used for sorting objects. Here’s a detailed comparison of the two:
Comparable
Purpose: Defines the natural ordering of objects.
Method:
compareTo(Object o)
Usage: Implemented by the class whose objects need to be ordered.
Single sorting sequence: Only one method,
compareTo
, can be implemented, meaning there is a single way to compare two objects.Modification: Requires modifying the class to implement the
Comparable
interface, which means the source code of the class must be altered.Example:
import java.util.ArrayList; import java.util.Collections; import java.util.List; class Student implements Comparable<Student> { private String name; private int rollNumber; public Student(String name, int rollNumber) { this.name = name; this.rollNumber = rollNumber; } @Override public int compareTo(Student other) { /* Sort by roll number -1 if current object < other object, 0 if the both objects are equal, 1 if the current object > other object */ int result = this.rollNumber - other.rollNumber; return result; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", rollNumber=" + rollNumber + '}'; } } public class Main { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("Alice", 3)); students.add(new Student("Bob", 1)); students.add(new Student("Charlie", 2)); Collections.sort(students); // Descending order // Collections.sort(students, Collections.reverseOrder()); for (Student student : students) { System.out.println(student); } } }
Comparator
Purpose: Defines an external comparison strategy for objects.
Method:
compare(Object o1, Object o2)
Usage: Implemented by a separate class to provide different ways of comparing objects.
Multiple sorting sequences: Can create multiple comparators to sort objects in different ways.
Modification: Does not require modifying the class whose instances are being compared. Instead, it provides a separate class to define the comparison logic.
Example:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 3, 20, 3.8));
students.add(new Student("Bob", 1, 22, 3.6));
students.add(new Student("Charlie", 2, 20, 3.9));
students.add(new Student("David", 2, 21, 3.7));
students.add(new Student("Eve", 2, 20, 3.9));
// Sort by roll number (descending), name (ascending), age (ascending), GPA (descending)
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int rollNumberComparison = Integer.compare(s2.getRollNumber(), s1.getRollNumber());
if (rollNumberComparison != 0) {
return rollNumberComparison;
}
int nameComparison = s1.getName().compareTo(s2.getName());
if (nameComparison != 0) {
return nameComparison;
}
int ageComparison = Integer.compare(s1.getAge(), s2.getAge());
if (ageComparison != 0) {
return ageComparison;
}
return Double.compare(s2.getGpa(), s1.getGpa());
}
});
System.out.println("Sorted by roll number (descending), name (ascending), age (ascending), GPA (descending):");
for (Student student : students) {
System.out.println(student);
}
}
private static class Student {
private String name;
private int rollNumber;
private int age;
private double gpa;
public Student(String name, int rollNumber, int age, double gpa) {
this.name = name;
this.rollNumber = rollNumber;
this.age = age;
this.gpa = gpa;
}
public String getName() {
return name;
}
public int getRollNumber() {
return rollNumber;
}
public int getAge() {
return age;
}
public double getGpa() {
return gpa;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", rollNumber=" + rollNumber +
", age=" + age +
", gpa=" + gpa +
'}';
}
}
}
Example: Using Lambda expressions.
import java.util.*;
class Student {
private String name;
private int rollNumber;
private int age;
private double gpa;
public Student(String name, int rollNumber, int age, double gpa) {
this.name = name;
this.rollNumber = rollNumber;
this.age = age;
this.gpa = gpa;
}
public String getName() {
return name;
}
public int getRollNumber() {
return rollNumber;
}
public int getAge() {
return age;
}
public double getGpa() {
return gpa;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", rollNumber=" + rollNumber +
", age=" + age +
", gpa=" + gpa +
'}';
}
}
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 3, 20, 3.8));
students.add(new Student("Bob", 1, 22, 3.6));
students.add(new Student("Charlie", 2, 20, 3.9));
students.add(new Student("David", 2, 21, 3.7));
students.add(new Student("Eve", 2, 20, 3.9));
// Sort by roll number (descending), name (ascending), age (ascending), GPA (descending)
students.sort(Comparator
.comparing(Student::getRollNumber).reversed()
.thenComparing(Student::getName)
.thenComparing(Student::getAge)
.thenComparing(Comparator.comparingDouble(Student::getGpa).reversed())
);
System.out.println("Sorted by roll number (descending), name (ascending), age (ascending), GPA (descending):");
for (Student student : students) {
System.out.println(student);
}
}
}
Subscribe to my newsletter
Read articles from V A S G Reddy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by