Comparator & Comparable in Java

Hikmet Çakır
4 min readSep 24, 2022
Photo by Kelly Sikkema on Unsplash

In lots of our time, we need to sort a collection to make easier algorithm that fixs a problem and present more understandable output to end user.

Suppose that you’re working in a bank application, your customer needs to look up own payment history and you have to write this API which takes customer’s id value and returns his payment history. In this situation, you want to sort by newest payment history of customer in the beginning because everybody wants to see own newest payment history. Nobody wants to see oldest payment history in the beginning. In like this situations, we need to sort a collection which contains payment history datas and Comparator and Comparable is used for this operation.

Both Comparator and Comparable are functional interfaces because they contain only one abstract method to implement. Both Comparator and Comparable can be used with lambdas due to this reason. This is awesome, isn’t it?

Comparable

Comparator is located inside java.lang and it has an abstract method which its name is compare. Compare method’s signature is compareTo(T o).

How It Can Be Used

Suppose that, there is a Food class which has id, name and price values. Additionally, it overrides toString() method to take understandable output. It implements Comparable interface. It can be used easily to sort a collection that contains Food objects’ list.

Let’s practice it. The code which I’ve shared in the below sorts our Food collection by price value. Firstly Food objects are created with own constructors then they are combine inside a List collection. Secondly, they are being sorted with Collections class. To sort a list, Collections class is generally preferred. Lastly they are printed.

CLI OutputSpaghetti : Price=8.0, ID=4ac08123-40fa-4a2d-ad3e-5a5ba64ef8bb
Cheeseburger : Price=10.0, ID=a1adffac-464d-4ada-a364-6547d72a82ec
Margherita : Price=13.0, ID=da2dfa55-b933-4d9f-8030-78aa5c811e5b

In this code, we can directly put our menu list to sort method because Food class implements Comparable interface. If it doesn’t implement Comparable interface, an error will be taken in compile time. In this situation to solve error, we can use Comparator interface.

Comparator

Comparator is located inside java.util and it is a functional interface, too.

int compare(T o1, T o2)

If you look up inside Comparator class. Many methods is being seemed but this situation doesn’t express that Comparator isn’t a functional interface because functional interface definition is that if a class has only one abstract method. Additionally, it’s called a functional interface and it can be marked with @FunctionalInterface annotation

Maybe, you didn’t catch it and asking that what about equals method inside Comparator class? In fact, each class extends Object class in Java therefore this equals method is overrided by Object class.

Sorting With Comparator

Suppose that, there is a Person object which has id, fullName and age values and we sometimes need to sort it by id or fullName or age. How can It be accomplised? Let’s do it.

As I said before, our person objects is defined and It contains three fields which are id, fullName and age and It doesn’t implement Comparable interface.

CLI Output
Nathaniel French Age=24, ID=8259fd57-1284-47a6-b7ba-b0274abac474
John Frazier Age=25, ID=3214b71d-e07e-457e-8d30-0fc3b4d3a149
Werner Schafer Age=34, ID=13346176-c8c6-4269-86f8-8ab8a783821b

Let’s analyze it. Firstly three objects are created and combined inside a List collection then it seems three Comparators and to sort, Collections was used and in the lastest, they are being printed.

In this code to sort Comparator.comparingInt was used. This expression is used for ascending sorting. There are many useful method to write easily sorting algorithm.

1- reversed():Comparator<T>2- thenComparing(Comparator<? super T>):Comparator<T>3- thenComparing(
Function<? super T, ? extends U>,
Comparator<? super U>):Comparator<T>
4- thenComparing(Function<? super T, ? extends U>):Comparator<T>5- thenComparingInt(ToIntFunction<? super T>):Comparator<T>6- thenComparingLong(ToLongFunction<? super T>):Comparator<T>7- thenComparingDouble(ToDoubleFunction<? super T>):Comparator<T>8- reverseOrder(): Comparator<T>9- naturalOrder(): Comparator<T>10- nullsFirst(Comparator<? super T>):Comparator<T>11- nullsLast(Comparator<? super T>):Comparator<T>12- comparing(Function<? super T, ? extends U>,
Comparator<? super U>): Comparator<T>
13- comparing(Function<? super T, ? extends U>):Comparator<t>14- comparingInt(ToIntFunction<? super T>):Comparator<T>15- comparingLong(ToLongFunction<? super T>):Comparator<T>16- comparingDouble(ToDoubleFunction<? super T>):Comparator<T>

Now let’s look up to other two comparators. First Comparator which is byFullName sort by fullName. If it is put to Collections like this :

Collections.sort(meeting, byFullName);

The output will be :

John Frazier Age=25, ID=bf963e34-ad45-496e-b62f-1b8d05494e88
Werner Schafer Age=34, ID=ea07eb3d-c37f-4799-80ff-2cc0b6e0f486
Nathaniel French Age=24, ID=9eafcca4-5f71-434b-a2d4-ab28446c17c4

If the other one which is byAgeDescending is put to Collections, the output will be :

Werner Schafer Age=34, ID=989b39a5-0841-4b62-9b75-0ea39fdd0622
John Frazier Age=25, ID=a2d85e84-47f6-435d-8459-ffbeac7c4243
Nathaniel French Age=24, ID=6e0b04e0-8209-4879-ad99-fe8acf8834ab

Don’t forget : if id is a integer value, arg1.id - arg2.id sorts in ascending order and arg2.id - arg1.id sorts in descending order.

I hope everything’s clear for you. If you don’t understand any part, feel free ask me. Additionally, I used various resource for prepare this essay. I indicated in following. You can check out.

  • OCP Study Guide 1Z0–809 — Jeanne Boyarsky & Scott Selikoff
  • Java Complete Reference — Herbert Schildt
  • Head First Java — Bert Bates and Kathy Sierra

--

--