Comparable and Comparator in Java: When we perform some operation at some time, we need sorting. As we have in our previous post, Java programming language provides some inbuilt methods to sort the primitive data types like array or wrapper classes array or list.
Before learning how to use Comparable and Comparator in Java, let’s rewind and learn how we can sort the array/list primitive types and wrapper class. We try to learn the uses of Comparable and Comparator in Java.
package com.journaldev.sort; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class JavaObjectSorting { /** * This class shows how to sort primitive arrays, * Wrapper classes Object Arrays * @param args */ public static void main(String[] args) { //sort primitives array like int array int[] intArr = {5,9,1,10}; Arrays.sort(intArr); System.out.println(Arrays.toString(intArr)); //sorting String array String[] strArr = {"A", "C", "B", "Z", "E"}; Arrays.sort(strArr); System.out.println(Arrays.toString(strArr)); //sorting list of objects of Wrapper classes List<String> strList = new ArrayList<String>(); 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); } }
The above example shows how easy it is to sort an Array and list object simply by calling Arrays.sort() and Collections.sort(). But in the same way, we can not use the objects of custom classes. To do that, we need to implement the Comparable interface in your custom class and need to implement the abstract method, which is present inside the comparable interface.
public abstract int compareTo(T obj)
The comparable interface has only one abstract method mentioned above, so according to the abstract class rule, we need to implement the abstract method in our class; otherwise, we need to declare our class as abstract.
Java provides two interfaces to sort the custom class objects:
- Comparable
- Comparator
Using Comparable Interface
This comparable object can compare itself with other objects, but the class must implement java.lang.Comparable interface to compare its instance. For the sorting, you must override the comparable interface’s compareTo ().
// A Java program to demonstrate use of Comparable import java.io.*; import java.util.*; // A class 'Movie' that implements Comparable class Movie implements Comparable<Movie> { private double rating; private String name; private int year; // Used to sort movies by year public int compareTo(Movie m) { return this.year - m.year; } // Constructor public Movie(String nm, double rt, int yr) { this.name = nm; this.rating = rt; this.year = yr; } // Getter methods for accessing private data public double getRating() { return rating; } public String getName() { return name; } public int getYear() { return year; } } // Driver class class Main { public static void main(String[] args) { ArrayList<Movie> list = new ArrayList<Movie>(); list.add(new Movie("Force Awakens", 8.3, 2015)); list.add(new Movie("Star Wars", 8.7, 1977)); list.add(new Movie("Empire Strikes Back", 8.8, 1980)); list.add(new Movie("Return of the Jedi", 8.4, 1983)); Collections.sort(list); System.out.println("Movies after sorting : "); for (Movie movie: list) { System.out.println(movie.getName() + " " + movie.getRating() + " " + movie.getYear()); } } }
When we try to sort custom class objects with comparable help, we can use only one attribute for sorting, but if you try to sort with multiple attributes, you have to use the Comparator.
Note: When you try to use comparable, you have to use the base class
Using Comparator
When we are sorting a custom class object using comparable, we are using the same class, and we can also use one attribute for sorting. So, because of those problems, a Comparator is introduced, in which we can make a separate class for each attribute and use the Comparator interface. The compareTo() method is incomparable in the comparator, and we need to override the compare() method.
The comparator class object is capable of comparing two objects of different classes. The syntax of compare methods is
public int compare(Object obj1, Object obj2):
This interface is present in java.util package, and it has two methods in it
- compare(Object obj1, Object obj2)
- equals(Object element)
Method of collection classes for sorting the List elements: we are using the sort method, and the syntax looks like the below
// To sort a given list. ComparatorClass must implement
// Comparator interface.
public void sort(List list, ComparatorClass c)
How to do collections.sort() work?
When we call the sort method, it internally calls the compare method and does the comparison.
Return 1: If the first element is greater than the second element
Return -1: If the second element is greater than the first element
Return 0: If both the elements are equals
The compare method uses this result and does swapping if required.
//A Java program to demonstrate Comparator interface import java.io.*; import java.util.*; // A class 'Movie' that implements Comparable class Movie implements Comparable<Movie> { private double rating; private String name; private int year; // Used to sort movies by year public int compareTo(Movie m) { return this.year - m.year; } // Constructor public Movie(String nm, double rt, int yr) { this.name = nm; this.rating = rt; this.year = yr; } // Getter methods for accessing private data public double getRating() { return rating; } public String getName() { return name; } public int getYear() { return year; } } // Class to compare Movies by ratings class RatingCompare implements Comparator<Movie> { public int compare(Movie m1, Movie m2) { if (m1.getRating() < m2.getRating()) return -1; if (m1.getRating() > m2.getRating()) return 1; else return 0; } } // Class to compare Movies by name class NameCompare implements Comparator<Movie> { public int compare(Movie m1, Movie m2) { return m1.getName().compareTo(m2.getName()); } } // Driver class class Main { public static void main(String[] args) { ArrayList<Movie> list = new ArrayList<Movie>(); list.add(new Movie("Force Awakens", 8.3, 2015)); list.add(new Movie("Star Wars", 8.7, 1977)); list.add(new Movie("Empire Strikes Back", 8.8, 1980)); list.add(new Movie("Return of the Jedi", 8.4, 1983)); // Sort by rating : (1) Create an object of ratingCompare // (2) Call Collections.sort // (3) Print Sorted list System.out.println("Sorted by rating"); RatingCompare ratingCompare = new RatingCompare(); Collections.sort(list, ratingCompare); for (Movie movie: list) System.out.println(movie.getRating() + " " + movie.getName() + " " + movie.getYear()); // Call overloaded sort method with RatingCompare // (Same three steps as above) System.out.println("\nSorted by name"); NameCompare nameCompare = new NameCompare(); Collections.sort(list, nameCompare); for (Movie movie: list) System.out.println(movie.getName() + " " + movie.getRating() + " " + movie.getYear()); // Uses Comparable to sort by year System.out.println("\nSorted by year"); Collections.sort(list); for (Movie movie: list) System.out.println(movie.getYear() + " " + movie.getRating() + " " + movie.getName()+" "); } }
If you still have any doubts, then you can refer to the below method
Comparable vs Comparator
Comparable interface | Comparator interface |
---|---|
Present in java.lang package | Present in java.util package |
Defines only one important method i.e. public int compareTo(Object obj); | Defines 2 method i.e.;public int compare(Object obj1, Object obj2); public boolean equals(Object object); |
It is used for default natural sorting order[DNSO] | This is preferred for customized sorting order [CSO] |
This interface needs to be implemented in the same class for which sorting is required | A separate class is required to implement the Comparator interface |
Elements of List can be sorted using a comparable interface example: Collection.sort(listItems); | Elements of List can be sorted using comparator interface example: Collection.sort(listItems, comparator); |
String & wrapper classes’ like Integer, Double, etc implement comparable interface | There are very few classes that implement a Comparator interface |