Tuesday, September 6, 2016

Java Comparable Interface and compareTo() Example

Hello, guys, today I am going to talk about one of the fundamental concepts in Java, defining the natural ordering of the objects e.g. lexicographical order for String and numerical order for Number classes e.g. Integer, Double, Float etc. The compareTo() method is defined in the java.lang.Comparable interface. It is used to define the natural ordering of an object e.g. String class override compareTo() to define the lexicographical order for String objects. Integer class override compareTo() to define the numeric ordering of integer objects. Similarly, you can override compareTo() method by implementing Comparable interface to define the natural order on which you want to order your object. For example, an Order should be ordered by order id hence compareTo() must provide logic for that.

Now, the question comes where does this natural ordering is required? Why do you need it in the first place? Well, in real world application, you are not dealing with just one object, you deal with a collection of objects. For example, in an e-commerce system you have millions of orders and if you want to display them, you cannot display in any random order, that won't do any benefit. You need to print or display them in an order which makes sense. The most common order is known as the natural order e.g. list of orders ordered by their OrderId.

The compareTo() method is mainly used in sorting process. In Java programs, when you often sort a list of object by calling Collections.sort(list), they are sorted based upon their natural order which is defined by compareTo() method. You should also remember that compareTo() returns a positive number if the current object is greater than given object, a negative number if current (this) object is less than given object and zero if both objects are equal.

One of the subtle detail about compareTo() is that it must match with equals() method e.g. if objects are equal with equals() then their compareTo() must return zero, failing to oblige this rule can create problems if you store your objects which uses both equals() and compareTo() method e.g. TreeSet and TreeMap.  See Core Java Volume 1 - Fundamentals by Cay S. Horstmann to learn more such details about compareTo() method in Java.

Java compareTo() Example

There are a lot of classes in Java which implements compareTo() method e.g. String, Integer, Long, Float, Double etc. You can see their implementation and how they work by running these examples. For example, let's say, you have a list of String and you want to sort them in increasing order. You don't need to do anything, this ordering is defined in the compareTo() method of java.lang.String class as shown below:

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;

    int k = 0;
    while (k < lim) {
      char c1 = v1[k];
      char c2 = v2[k];
      if (c1 != c2) {
        return c1 - c2;
    return len1 - len2;

This method compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string.

In lexicographic ordering, If two strings are different, then either they have different characters at some index that is a valid index for both strings, or their lengths are different, or both.

All you need to do is just call the Collections.sort() method to sort the list of String. This method uses Strategy design pattern and calls compareTo() method which defines sorting strategy of the object. Every object is free to override how they compare, which we will see in next section. Btw, here is a diagram which shows that both String and wrapper classes implement Comparable interface in Java:

Java Comparable Interface and compareTo() Example

Java Comparable and ComapreTo Example

Now, let's how to override compareTo() method for a user object. In this program, we'll create a user defined object called order which has fields like OrderId (a non-negative number), Customer details and total amount. The natural order for this object is by OrderId e.g. on increasing order, OrderId with 1 will come before OrderId 2 and on decreasing order, Order with Id 2 will come before an object with Id 1.

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

 * Java Program to show compareTo() example
 * and Comparable example

public class Main {

  public static void main(String[] args) {

    // let's create couple of order to compare
    Order first = new Order(1, "abc", BigDecimal.TEN);
    Order second = new Order(2, "xyz", new BigDecimal("10"));
    Order third = new Order(3, "kbc", BigDecimal.ONE);

    // let's compare first and second order
    int result = first.compareTo(second);
    if (result > 0) {
      System.out.println("first order is greater than second");
    } else if (result < 0) {
      System.out.println("first order is less than second");
    } else if (result == 0) {
      System.out.println("both orders are same");

    // let sort the order as per natural order defined by compareTo()
    List<Order> listOfOrders = new ArrayList<>();




 * A class which implements Comparable interface and overrides compareTo()
 * method. Make sure you use Generic and define type parameter for Comparable,
 * in this way, you don't need to cast Object to Order inside compareTo() method
class Order implements Comparable<Order> {
  private int id;
  private String customer;
  private BigDecimal total;

  public Order(int id, String customer, BigDecimal total) {
    this.id = id;
    this.customer = customer;
    this.total = total;

  public int compareTo(Order ord) {
    return this.id - ord.id;

  public String toString() {
    return "OrderId-" + id;


the first order is less than second
[OrderId-1, OrderId-2, OrderId-3]

You can see from the output that first order is less than second because id of the first order is 1 and id of second order are 2. So, when you sort them in increasing order, first order will come before second order, which is also evident from the second line of output.

Anyway, It's not that you are only limited to one order, you can, of course, define custom ordering e.g. ordering order by the customer, by date or even by the total amount, but Comparable is not for that. You need to use the Comparator interface and overrides its compare() method to define customized ordering similar to order by clause of SQL. You can learn more about the difference between Comparator and Comparable here.

That's all in this Java Comparable and compareTo() example. Along with equals(), hashcode(), and compare() methods, compareTo() is also one of the fundamentals every Java programmer should know. It's very important to define the ordering for data object because you don't want them sorted in any random order, so make sure when you create an object you provide an implementation for critical methods e.g. equals, hashcode, compare, toString and compareTo.

Other Java basic tutorials you may like
  • How to override equals() method in Java? (example)
  • How to override hashcode() method in Java? (example)
  • How to override compare() method in Java? (example)
  • How to override toString() method in Java? (example)
  • How to implement clone() method in Java? (example)
  • How to override clone() with a mutable field in Java? (example)
  • What is the difference between Comparable and Comparator in Java? (answer)

Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java In-Depth: Become a Complete Java Engineer!

No comments :

Post a Comment