The Differences Between Comparable and Comparator – How to Use Both Effectively

In Java, the Comparable and Comparator interfaces are highly useful when it comes to sorting collections of objects. Java provides some built-in methods to sort primitive types and wrapper classes. In this post, you’ll first learn how to sort arrays and lists with primitive types and wrapper classes, and then how to sort custom class objects using the Comparable and Comparator interfaces.

Sorting Primitive Arrays and Lists

First, here’s an example of how to sort primitive arrays or arrays of wrapper classes in Java. Below is the code to sort an array of integers and an array of strings:

package com.journaldev.sort; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class JavaObjectSorting { public static void main(String[] args) { // Sorting a primitive array (int) int[] intArr = {5, 9, 1, 10}; Arrays.sort(intArr); System.out.println(Arrays.toString(intArr)); // Sorting a string array String[] strArr = {"A", "C", "B", "Z", "E"}; Arrays.sort(strArr); System.out.println(Arrays.toString(strArr)); // Sorting a list of wrapper classes (Strings) List strList = new ArrayList<>(); strList.add("A"); strList.add("C"); strList.add("B"); strList.add("Z"); strList.add("E"); Collections.sort(strList); for (String str : strList) { System.out.print(" " + str); } } }

Output:

 [1, 5, 9, 10] [A, B, C, E, Z] A B C E Z

Sorting Custom Class Objects

Sorting arrays of custom class objects requires more effort. Java offers the Comparable and Comparator interfaces for this purpose. Here’s an example of how to sort an array of Employee objects:

package com.journaldev.sort; public class Employee { private int id; private String name; private int age; private long salary; public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public long getSalary() { return salary; } public Employee(int id, String name, int age, int salary) { this.id = id; this.name = name; this.age = age; this.salary = salary; } @Override public String toString() { return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" + this.salary + "]"; } }

Attempting to sort this array directly results in a runtime exception, as Employee does not implement the Comparable interface.

Solution with Comparable:

To resolve this, we implement the Comparable interface and override the compareTo method to allow sorting Employee objects by their id by default:

package com.journaldev.sort; public class Employee implements Comparable { private int id; private String name; private int age; private long salary; @Override public int compareTo(Employee emp) { return this.id - emp.id; } @Override public String toString() { return "[id=" + this.id + ", name=" + this.name + ", age=" + this.age + ", salary=" + this.salary + "]"; } }

After this change, you can now sort the Employee array:

Employee[] empArr = new Employee[4]; empArr[0] = new Employee(10, "Mikey", 25, 10000); empArr[1] = new Employee(20, "Arun", 29, 20000); empArr[2] = new Employee(5, "Lisa", 35, 5000); empArr[3] = new Employee(1, "Pankaj", 32, 50000); Arrays.sort(empArr); System.out.println("Default Sorting:\n" + Arrays.toString(empArr));

Output:

 [id=1, name=Pankaj, age=32, salary=50000], [id=5, name=Lisa, age=35, salary=5000], [id=10, name=Mikey, age=25, salary=10000], [id=20, name=Arun, age=29, salary=20000]

Sorting by Different Criteria with Comparator

While the Comparable interface only allows for one default sorting criterion, the Comparator interface enables sorting by multiple criteria. Below are some custom Comparator implementations that allow sorting employees by Salary, Age, or Name:

import java.util.Comparator; public class Employee { public static Comparator SalaryComparator = new Comparator() { @Override public int compare(Employee e1, Employee e2) { return (int) (e1.getSalary() - e2.getSalary()); } }; public static Comparator AgeComparator = new Comparator() { @Override public int compare(Employee e1, Employee e2) { return e1.getAge() - e2.getAge(); } }; public static Comparator NameComparator = new Comparator() { @Override public int compare(Employee e1, Employee e2) { return e1.getName().compareTo(e2.getName()); } }; }

These comparators can be used to sort the Employee array by different criteria:

Arrays.sort(empArr, Employee.SalaryComparator); System.out.println("Sorted by Salary:\n" + Arrays.toString(empArr)); Arrays.sort(empArr, Employee.AgeComparator); System.out.println("Sorted by Age:\n" + Arrays.toString(empArr)); Arrays.sort(empArr, Employee.NameComparator); System.out.println("Sorted by Name:\n" + Arrays.toString(empArr));

Conclusion

In Java, the Comparable and Comparator interfaces provide a flexible way to sort custom objects. The Comparable interface defines a fixed default sorting order, which is ideal for cases where a unified sorting method is needed. On the other hand, the Comparator interface allows sorting by different criteria, making it useful when flexible, situation-dependent sorting is required.
By using Comparator, you can define as many sorting methods as needed and choose the appropriate criterion—such as salary, age, or name—depending on the context. This flexibility helps meet the varying demands of practical applications.

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: