Java Comparable tutorial with examples will help you understand how to use Java Comparable interface in an easy way. Comparable interface in Java is used to define an object’s natural ordering. The Comparable interface has only one method named compareTo
.
The comparable interface is contained in the java.lang package which is imported by default in the code. You do not need to import any package using the import statement to use the Comparable interface in your code.
1 |
int compareTo(T object) |
The compareTo
method returns a negative number if this object is less than the specified object, zero if they are an equal, and a positive number if this object is greater than the specified object.
Please note that the compareTo
method throws NullPointerException if the specified object is null (because null is not an object of any class) and ClassCastException if the specified object type is a mismatch.
In order to define the natural ordering of the objects of the class, the class must implement Comparable interface and define the compareTo
method. Once the compareTo
method is defined, it will be referred automatically when the objects of the class are being sorted using sort
method of the Collections
class or the Arrays class. The Comparable interface is useful when you want to sort the objects of a custom class by attributes of it. For example, if you have an Employee class and you want to sort the employee objects by age or salary.
Consider below given MobilePhone class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class MobilePhone{ String name; double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } } |
It has two properties, a mobile phone name, and its price. You can use the Comparable interface to sort the mobile phones stored in an ArrayList by their price in ascending order as given in the below example.
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import java.util.ArrayList; import java.util.Collections; class MobilePhone implements Comparable<MobilePhone>{ String name; double price; public MobilePhone(String name, double price){ this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int compareTo(MobilePhone m) { if(this.price < m.price) return -1; else if (this.price > m.price) return 1; else return 0; } //just for nice printing purpose public String toString(){ return "(" + this.getName() + ", " + this.getPrice() + ")"; } } public class ComparableExample { public static void main(String[] args) { MobilePhone m1 = new MobilePhone("Apple iPhone XS", 1000); MobilePhone m2 = new MobilePhone("Apple iPhone XR", 799); MobilePhone m3 = new MobilePhone("Apple iPhone X", 899); MobilePhone m4 = new MobilePhone("Samsung Galaxy s10", 699); MobilePhone m5 = new MobilePhone("Samsung Galaxy Note 10", 799); ArrayList<MobilePhone> aListMobiles = new ArrayList<MobilePhone>(); aListMobiles.add(m1); aListMobiles.add(m2); aListMobiles.add(m3); aListMobiles.add(m4); aListMobiles.add(m5); //List without sorting System.out.println("Before sorting the objects"); System.out.println(aListMobiles); /* * Sort the ArrayList using Collections.sort method * which will internally invoke the compareTo method we * defined in the MobilePhone class. */ Collections.sort(aListMobiles); //List after sorting by price System.out.println("After sorting the objects"); System.out.println(aListMobiles); } } |
Output
1 2 3 4 |
Before sorting the objects [(Apple iPhone XS, 1000.0), (Apple iPhone XR, 799.0), (Apple iPhone X, 899.0), (Samsung Galaxy s10, 699.0), (Samsung Galaxy Note 10, 799.0)] After sorting the objects [(Samsung Galaxy s10, 699.0), (Apple iPhone XR, 799.0), (Samsung Galaxy Note 10, 799.0), (Apple iPhone X, 899.0), (Apple iPhone XS, 1000.0)] |
In the above Comparable example, the MobilePhone class implements the Comparable interface and defines the compareTo
method. The compareTo
method compares the current object with another object by price. It returns -1 if this object’s price is less than another object’s price, 0 if the prices are equal, and 1 if this object’s price is greater than another object’s price. You can return any positive or negative numbers instead of 1 and -1 respectively.
Instead of comparing the price using if-else statement, you can also write a short compareTo
method as given below.
1 2 3 |
public int compareTo(MobilePhone m) { return (int)(this.price - m.price); } |
How to sort objects in descending order using the Comparable interface in Java?
I have explained how to sort objects in ascending order in the above example. To sort the objects in the descending order all we have to do is to change the compareTo
method to return opposite values. Let’s have a look at the modified compareTo
method.
1 2 3 |
public int compareTo(MobilePhone m) { return (int)(m.price - this.price); } |
So instead of subtracting another object’s price from this object, we subtracted this object’s price from another object’s price to sort the objects in the descending order. Here is the output of the same program with modified compareTo
method.
1 |
[(Apple iPhone XS, 1000.0), (Apple iPhone X, 899.0), (Apple iPhone XR, 799.0), (Samsung Galaxy s10, 699.0)] |
As you can see from the output, the objects are now sorted by the price in descending order.
When we add objects of a class which implements Comparable interface to the Set (HashSet, TreeSet), they are automatically added in the defined sorted order without the need of additional Comparator object.
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 53 54 55 56 57 58 59 60 61 62 |
import java.util.Collections; import java.util.TreeSet; class MobilePhone implements Comparable<MobilePhone>{ String name; double price; public MobilePhone(String name, double price){ this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int compareTo(MobilePhone m) { if(this.price < m.price) return -1; else if (this.price > m.price) return 1; else return 0; } //just for nice printing purpose public String toString(){ return "(" + this.getName() + ", " + this.getPrice() + ")"; } } public class ComparableExample { public static void main(String[] args) { MobilePhone m1 = new MobilePhone("Apple iPhone XS", 1000); MobilePhone m2 = new MobilePhone("Apple iPhone XR", 799); MobilePhone m3 = new MobilePhone("Apple iPhone X", 899); MobilePhone m4 = new MobilePhone("Samsung Galaxy s10", 699); MobilePhone m5 = new MobilePhone("Samsung Galaxy Note 10", 799); TreeSet<MobilePhone> setMobiles = new TreeSet<MobilePhone>(); setMobiles.add(m1); setMobiles.add(m2); setMobiles.add(m3); setMobiles.add(m4); setMobiles.add(m5); System.out.println(setMobiles); } } |
Output
1 |
[(Samsung Galaxy s10, 699.0), (Apple iPhone XR, 799.0), (Apple iPhone X, 899.0), (Apple iPhone XS, 1000.0)] |
As you can see from the output, mobile phones are automatically sorted by price in the TreeSet. Noticed something else in the output? Where is our beloved Samsung Galaxy Note 10 m5
object? It is missing from the output. It is because TreeSet is an implementation of the Set interface which accepts only unique elements.
In our compareTo
method, if any of the two products have the same price, we call them equal regardless of its name. Since m2
and m5
objects have the same price, we cannot add m5
after adding m2
to the same TreeSet object. If we want to, we need to change the compareTo
method to take the mobile name into account while comparing them. Always include all the attributes of an object that makes them different in the compareTo
method.
You can have only one compareTo
method in a class. What if you want to sort the objects in more than one way? For example, if you want to sort the Employee objects by salary in ascending order and by age in descending order? In this case, you need to use the Comparator interface instead of Comparable interface. Please visit the Java Comparator tutorial to know more.
Java Comparable Examples
- Search elements of ArrayList using Comparable interface
- Sort elements of LinkedList using Comparable interface
- Sort LinkedHashMap by keys using Comparable
- Sort LinkedHashMap by values using Comparable
- How to create TreeMap objects using Comparable interface
- How to sort HashSet using Comparable
- How to sort TreeSet using Comparable
- How to sort LinkedHashSet using Comparable
- How to sort Java Vector using Comparable
- How to find the minimum or maximum Vector element using the Comparable
References:
Java Comparable interface Javadoc
Please let me know if you liked the Java Comparable tutorial with examples in the comments section below.