What is compareTo()

If you are new to comparing objects in Java then you need to know that there are multiple ways for comparing objects and each way consists of invoking a method. A few methods which are used for comparing objects include:

Apart from these methods there is also == operator which can be used for comparison of primitive data type values.

You may follow the links above to see how equals and compareTo methods behave. In this article, we shall understand how does compareTo method works.

Purpose of compareTo

compareTo literally means we are trying to compare the current object in context to another object. So we have one object about which we know or have reference to. And we are asking the this object in context if it is equal to another object or not.

One more important purpose of compareTo method is that it provides natural sorting order which means that the objects of a class implementing the compareTo method can be naturally sorted. This natural sorting order is used in collection classes like TreeSet or TreeMap. For example if we have a class named Computer which implements compareTo method, the following declaration will make sure that multiple objects of class Computer can be stored in TreeSet in sorted order:

TreeSet ts = new TreeSet();
ts.add(new Computer("Sony","150GB","2.2GHz"));
ts.add(new Computer("Apple","320GB","4.0GHz"));
ts.add(new Computer("Toshiba","500GB","3.0GHz"));

Pre-requsite for implementing compareTo method

It is required that the classes which want natural sorting order to be available to them implement the Comparable interface. This interface makes the class objects comparable to each other. The interface Comparable has only one method defined inside it:

public int compareTo(Object o)

Thus in our above example, the class Computer must be implementing the Comparable interface for its objects to be naturally sorted in collections.

Working of compareTo

The actual sorting order of objects is defined by compareTo method. Any logic can be written inside it as per requirement. For example, the java.lang.String class makes sure the String objects are naturally sorted as per the characters present in the string. Our demo class Computer has written logic to compare the Brand name and provide sorting order accordingly.

The following is the source code of Computer class as discussed above. Here we are comparing the member instance variable named brand_name and deciding the sorting order of objects of Computer class.

package com.example;

public class Computer implements Comparable{
    private String brand_name;
    private String hdd_capacity;
    private String processor_speed;

    public String getBrand_name() {
        return brand_name;
    }

    public void setBrand_name(String brand_name) {
        this.brand_name = brand_name;
    }

    public String getHdd_capacity() {
        return hdd_capacity;
    }

    public void setHdd_capacity(String hdd_capacity) {
        this.hdd_capacity = hdd_capacity;
    }

    public String getProcessor_speed() {
        return processor_speed;
    }

    public void setProcessor_speed(String processor_speed) {
        this.processor_speed = processor_speed;
    }

    Computer(String brand,String capacity,String speed){
        setBrand_name(brand);
        setHdd_capacity(capacity);
        setProcessor_speed(speed);
    }

    @Override
    public int compareTo(Object o){
        Computer another_comp = (Computer) o;
        return (this.getBrand_name().compareTo(another_comp.getBrand_name()));
    }
}

Return value of compareTo

The return value of this method gives and idea whether the current object in context is smaller, equal or greater than the object being compared to. As you can notice, the return type of compareTo method is int. Generally there type of values are implied as return value. These are -ve, 0 or +ve with -ve being any negative integer and similarly positive being any positive integer.

The javadoc for compareTo method in the Comparable interfaces states the following:

a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

compareTo implementation in JDK

The compareTo method has been defined in many class inside JDK itself. The following is a list of classes which have defined the compareTo method:

1) java.lang.String
2) All wrapper classes (java.lang.Integer, java.lang.Float, java.lang.Long etc.)
3) java.math.BigDecimal
4) java.math.BigInteger
5) java.util.Calendar

Those were the main classes implementing the Comparable interface in Java.For a list of all classes that implement the Comparable interface and hence override the compareTo method, go to :

Comparable implementing classes

Best practices for overriding compareTo method

When you are defining your custom implementation of compareTo method, always keep in mind the following points about how to override the compareTo method in Java class.

  • Whenever possible, make use of already available methods. For example in our Computer demo, we made use of compareTo implementation available in the String class. Thus if you are trying to compare instance member variables, use the compareTo of those instance members if available.
  • The result of compareTo method should be in compliance with equals method. This means that if for two objects equals method returns true then the compareTo method should also return 0. If not done so the use of the objects with Set collection can result in unexpected behavior.
  • Since the argument of compareTo method is of type Object and we need to type cast it to the class whose objects we are going to compare as shown in Computer demo. It is always recommended to throw a ClassCastException if the object can’t be type-casted properly. However if you are using generics then there is no need to go for ClassCastException. Following is an example of using generics with Comparable interface.

    public class Test implements Comparable<String>{
    
        String a;
    
        public int compareTo(String o) {
            return this.a.compareTo(o);
        };
    }
    
  • If primitive data types are involved in the comparison then it is a good practice either to use wrapper classes or if required == operator and decide the result as per the return value of == operator. The use of subtraction, addition or other arithmetic operations is discouraged because of overflow and underflow issues involved.
  • As with hashcode method, it is best practice to start comparing the most significant member variable and then following up with less significant members. As soon as the result of comparison is decided, return the value and stop comparing other less significant members. For example, the String class starts comparing the characters of Strings starting from the rightmost character and when it finds a difference in characters, it returns the result without proceeding further.

Javadoc for compareTo

Finally the javadoc for compareTo method from Comparable interface is being reproduced here for reference. It is recommended that you go through this once for better understanding.

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive. The implementer must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)

The implementer must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.

Finally, the implementer must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is “Note: this class has a natural ordering that is inconsistent with equals.”

Parameters:
o – the Object to be compared.
Returns:
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Throws:
ClassCastException – if the specified object’s type prevents it from being compared to this Object.

Overriding compareTo() method in Java admin Core Java
What is compareTo() If you are new to comparing objects in Java then you need to know that there are multiple ways for comparing objects and each way consists of invoking a method. A few methods which are used for comparing objects include: equals compare compareTo Apart from these methods there is also ==...
<h2>What is compareTo()</h2> If you are new to comparing objects in Java then you need to know that there are multiple ways for comparing objects and each way consists of invoking a method. A few methods which are used for comparing objects include: <ul> <li>equals</li> <li><a href="http://www.javaexperience.com/compare-objects-using-comparator-in-java/">compare</a></li> <li><a href="http://www.javaexperience.com/compare-objects-using-comparator-in-java/">compareTo</a></li> </ul> Apart from these methods there is also <strong>== operator</strong> which can be used for comparison of primitive data type values. You may follow the links above to see how equals and compareTo methods behave. In this article, we shall understand how does compareTo method works. <h2>Purpose of compareTo</h2> compareTo literally means we are trying to compare the current object in context to another object. So we have one object about which we know or have reference to. And we are asking the this object in context if it is equal to another object or not. One more important purpose of compareTo method is that it provides <strong>natural sorting order</strong> which means that the objects of a class implementing the compareTo method can be naturally sorted. This natural sorting order is used in collection classes like <a href="http://www.javaexperience.com/difference-between-treemap-and-treeset-in-java/">TreeSet or TreeMap</a>. For example if we have a class named Computer which implements compareTo method, the following declaration will make sure that multiple objects of class Computer can be stored in TreeSet in sorted order: 1 <h2>Pre-requsite for implementing compareTo method</h2> It is required that the classes which want natural sorting order to be available to them implement the <strong>Comparable interface</strong>. This interface makes the class objects comparable to each other. The interface Comparable has only one method defined inside it: 1 Thus in our above example, the class Computer must be implementing the Comparable interface for its objects to be naturally sorted in collections. <h2>Working of compareTo</h2> The actual sorting order of objects is defined by compareTo method. Any logic can be written inside it as per requirement. For example, the <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/String.html">java.lang.String class</a> makes sure the String objects are naturally sorted as per the characters present in the string. Our demo class Computer has written logic to compare the Brand name and provide sorting order accordingly. The following is the source code of Computer class as discussed above. Here we are comparing the member instance variable named brand_name and deciding the sorting order of objects of Computer class. 1 <h2>Return value of compareTo</h2> The return value of this method gives and idea whether the current object in context is smaller, equal or greater than the object being compared to. As you can notice, the return type of compareTo method is int. Generally there type of values are implied as return value. These are -ve, 0 or +ve with -ve being any negative integer and similarly positive being any positive integer. The javadoc for compareTo method in the Comparable interfaces states the following: <blockquote> a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. </blockquote> <h2>compareTo implementation in JDK</h2> The compareTo method has been defined in many class inside JDK itself. The following is a list of classes which have defined the compareTo method: 1) java.lang.String 2) All wrapper classes (java.lang.Integer, java.lang.Float, java.lang.Long etc.) 3) java.math.BigDecimal 4) java.math.BigInteger 5) java.util.Calendar Those were the main classes implementing the Comparable interface in Java.For a list of all classes that implement the Comparable interface and hence override the compareTo method, go to : <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html">Comparable implementing classes</a> <h2>Best practices for overriding compareTo method</h2> When you are defining your custom implementation of compareTo method, always keep in mind the following points about how to override the compareTo method in Java class. <ul> <li> Whenever possible, make use of already available methods. For example in our Computer demo, we made use of compareTo implementation available in the String class. Thus if you are trying to compare instance member variables, use the compareTo of those instance members if available. </li> <li> The result of compareTo method should be in compliance with equals method. This means that if for two objects equals method returns true then the compareTo method should also return 0. If not done so the use of the objects with Set collection can result in unexpected behavior. </li> <li> Since the argument of compareTo method is of type Object and we need to type cast it to the class whose objects we are going to compare as shown in Computer demo. It is always recommended to throw a ClassCastException if the object can't be type-casted properly. However if you are using generics then there is no need to go for ClassCastException. Following is an example of using generics with Comparable interface. 1 </li> <li> If primitive data types are involved in the comparison then it is a good practice either to use wrapper classes or if required == operator and decide the result as per the return value of == operator. The use of subtraction, addition or other arithmetic operations is discouraged because of overflow and underflow issues involved. </li> <li> As with <a href="http://www.javaexperience.com/java-dive-deep-into-hashcode-internals/">hashcode method</a>, it is best practice to start comparing the most significant member variable and then following up with less significant members. As soon as the result of comparison is decided, return the value and stop comparing other less significant members. For example, the String class starts comparing the characters of Strings starting from the rightmost character and when it finds a difference in characters, it returns the result without proceeding further. </li> </ul> <h2>Javadoc for compareTo</h2> Finally the javadoc for compareTo method from Comparable interface is being reproduced here for reference. It is recommended that you go through this once for better understanding. <blockquote> Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive. The implementer must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.) The implementer must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0. Finally, the implementer must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z. It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable <a href="http://www.javaexperience.com/exhaustive-differences-between-abstract-class-and-interface/">interface</a> and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals." Parameters: o - the Object to be compared. Returns: a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Throws: ClassCastException - if the specified object's type prevents it from being compared to this Object. </blockquote>
The following two tabs change content below.
I run this blog with lots of passion. In this website, you will find tutorials on Core Java, Spring, Struts, Web Applications, Portals and Database. Please support me and the website by sharing the posts on your facebook / twitter. You can tap the share button at the top of each post. Thanks for the support.