1. Java Comparable Interface & compareTo Method
We used TreeSet class in the past example on the Integer boxed type. The TreeSet knows how to compare two Integer boxed type because the Java Integer class implements Comparable interface. For user-defined types, one should sign the the Comparable interface contract so that Java Collection class like TreeSet knows how to compare two objects and choose which one is bigger. The Comparable interface has a contract method compareTo which will study two objects and returns an integer. This integer value is helpful to know the object bigger or smaller or equal with the compared object. In this example, we will use the Java TreeSet to store Product objects.
2. Java Comparable Interface
Since the past example on Java TreeSet used an Integer objects as its collection items, we had not dealt with the Comparable. The Java SDK object Integer already takes care of this interface and hence we stored these boxed types in the Java TreeSet in a sorted way with no issue.
For user defined type, like the Product class, we need to implement the Comparable interface. The compareTo method of this interface defines the Natural Sorting Order. This NSO is a default sorting order which defines the ascending order of the collection items.
3. Java Comparable Contract Method – compareTo
3.1 compareTo Method Significance
When we implement the Comparable interface, we must override the compareTo method. Below is the signature of the compareTo method:

This method takes an object o which will be compared with the calling object. Let us say, we are making call to the add method of the TreeSet and passing an object of the Product class. The add method of the TreeSet calls the compareTo method of the Product class and passes its collection object to it. But Why for the add? Because it needs to keep its items in a ordered way and needs to know which one is bigger between its collection of products versus the new incoming through the add method.
3.2 Which two objects are compered in compareTo?
In the above method Object o is from the collection class and ‘this’ reference in the body stands for the argument passed to the add method. To read this better, think of an Integer as a collection item and have a look at the below picture:

Now let us say we want to add item 7 to the TreeSet by calling add(7); The TreeSet is already having six numbers in it. Now in the compareTo method object o refers the collection of items 1,2,3,6 and 9. And ‘this’ object in the method body refers the argument to the call to the add(7) method. The TreeSet calls the compareTo method on the incoming object to the add method. This means, the TreeSet uses the boxed class of Integer representing 7 and makes a call to compareTo method on Integer 7 and passes its collection items one-by-one to it. Based on the method return value, it knows the 7 is bigger than one of its collection items being compared. Also it finds a correct place on its ordered items.
In our case, the Product class implements this compareTo method and the statement – returns positive or negative number to the caller. The caller, the TreeSet, uses this number to know how to perform the ordering. In the picture, you can see the how the calling object’s position in the collection of items is decided.
4. Complete Java Comparable Example – compareTo Usage
4.1 Create Products
In the past example on SortedSet, we added the Integers to it. In this example, we will try storing the Product in the Collection. At line 9, we create the
Java TreeSet to store Product
instances. Then we create Six products and add them to the TreeSet
instance. The moment we make call to
add method, we get a failure stating ‘Do not know how to compare two Products’. This is because TreeSet
wants to order the products to maintain Natural Sorting Order (Default) and it don’t know how to compare two Products. This means we need to implement Comparable
interface for our Product
class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//Sample 02: Create Set SortedSet<Product> set = new TreeSet<Product>(); //Sample 03: Create six Products Product p1 = new Product(101, "Pen"); Product p2 = new Product(102, "Pencil"); Product p3 = new Product(103, "Rubber"); Product p4 = new Product(104, "Writing Pad"); Product p5 = new Product(105, "Clips"); Product p6 = new Product(106, "Sharpner"); //Sample 05: Add Elements & Ensure Sorting of Custom Object set.add(p2); set.add(p4); set.add(p1); set.add(p3); set.add(p6); set.add(p5); |
4.2 Implement Comparable Interface
In the below code, you can see the Product class implements the Comparable interface. Now, the compiler demands to implement the compareTo method in the Product class. We will do that next.
1 2 3 |
//Sample 06: Make Product Comparable for //Natural Sorting Order public class Product implements Comparable{ |
4.3 Implement compareTo Method
The code below shows the compareTo method implementation. Recall, the method should return a number. It can be a positive number or negative number or zero. When method returns zero, the caller which is here a collection knows that both the objects are equal. Positive and Negative number helps the collection class in ordering the items.
The object o
is coming from the collection item. The ‘this’ reference is passed as an argument to the API method like
add,
contains etc. which calls for comparison. In the
compareTo method, we use only the Product ID (Line 5) and hence the sorting is done based on the ProdId of the Product
class. Note, when Product Id of the collection is bigger than the ‘this’ object, the method returns a negative integer and the argument passed to the TreeSet’s
add method moves to the left of the object ‘o
’. Have a look at the picture again above. This way, we end-up with Natural Sorting Order which is Smallest to Biggest. Java’s
Comparable interface advises to implement the
compareTo method to sort items in the Natural Sorting Order way.
1 2 3 4 5 6 |
//Sample 07: Implement Product Comparison @Override public int compareTo(Object o) { Product element = (Product)o; return this.ProdId - element.getProdId(); } |
After completing the above method, the call to TreeSet’s add method proceeds with no error. Now, we can go on with the TreeSet class implementation, which we left in Section 4.1.
4.4 Iterate & Print TreeSet of Products
Next, we write a custom method to iterate over the TreeSet
of Products. We saw similar function in the past examples. Below is the code:
1 2 3 4 5 6 7 |
//Sample 04: Traverse and Print the the Tree private static void printTree(SortedSet<Integer> set) { Iterator<Integer> itr = set.iterator(); while (itr.hasNext()) System.out.print(itr.next() + ","); System.out.println(); } |
Finally, we call this method after adding the items to the TreeSet.
1 |
printTree(set); |
5. Complete Example – compareTo Usage
TreeSetProduct.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//Sample 01: Package Required import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; public class TreeSetProduct { public static void main(String[] args) { //Sample 02: Create Set SortedSet<Product> set = new TreeSet<Product>(); //Sample 03: Create six Products Product p1 = new Product(101, "Pen"); Product p2 = new Product(102, "Pencil"); Product p3 = new Product(103, "Rubber"); Product p4 = new Product(104, "Writing Pad"); Product p5 = new Product(105, "Clips"); Product p6 = new Product(106, "Sharpner"); //Sample 05: Add Elements & Ensure Sorting of Custom Object set.add(p2); set.add(p4); set.add(p1); set.add(p3); set.add(p6); set.add(p5); printTree(set); } //Sample 04: Traverse and Print the the Tree private static void printTree(SortedSet<Integer> set) { Iterator<Integer> itr = set.iterator(); while (itr.hasNext()) System.out.print(itr.next() + ","); System.out.println(); } } |
Product.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import java.util.Objects; //Sample 06: Make Product Comparable for //Natural Sorting Order public class Product implements Comparable{ private int ProdId; private String ProdName; Product(int id, String name) { ProdId = id; ProdName = name; } @Override public String toString() { return ProdId + ":" + ProdName ; } public int getProdId() { return ProdId; } public void setProdId(int prodId) { ProdId = prodId; } public String getProdName() { return ProdName; } public void setProdName(String prodName) { ProdName = prodName; } @Override public int hashCode() { return Objects.hashCode(ProdId); } @Override public boolean equals(Object obj) { Product prod = (Product) obj; return (this.ProdId == prod.getProdId()); } //Sample 07: Implement Product Comparison @Override public int compareTo(Object o) { Product element = (Product)o; return this.ProdId - element.getProdId(); } } |
5. Watch Java Comparable Example as YouTube Video
Categories: Java
Tags: Comparable, compareTo, Natural Sorting Order