how2examples.com
Home - Introduction to Java Programming

Comparing Java Objects

It is a common requirement to compare instances of a class. The equals(Object) method can be used to simply check if two objects are the same. The java.lang.Comparable and java.util.Comparator interfaces are used to sort objects into a predictable order.

The java.lang.Comparable interface

The Comparable interface defines a int compareTo(T o) method. Implementations of int compareTo(T o) should compare the instance being invoked against the object specified by the single method argument. A negative integer should be returned if the instance is than the specified argument; zero if the instance and the specified argument are equal; or a positive integer if the instance is greater than the specified argument. What it means for an object to be less than, equal or greater than another instance of the same class is class-specific. The String class, which implements Comparable, compares instances lexicographically - i.e. the comparison is based on the Unicode value of each character in the strings.

Example of comparing instances of String.
Code snippet:
System.out.println("deer".compareTo("deer"));
System.out.println("bee".compareTo("kangaroo"));
System.out.println("zebra".compareTo("aardvark"));
Output from running code snippet:
0
-9
25

It is the int compareTo(T o) method of Comparable that the Arrays.sort(Object[]) method uses to sort object arrays.

Example of sorting an array of String objects.
Code snippet:
String[] a = {"zebra", "bee", "aardvark", "kangaroo", "deer"};
System.out.println("before sort: "+java.util.Arrays.toString(a));
java.util.Arrays.sort(a);
System.out.println("after sort:  "+java.util.Arrays.toString(a));
Output from running code snippet:
before sort: [zebra, bee, aardvark, kangaroo, deer]
after sort:  [aardvark, bee, deer, kangaroo, zebra]

As Arrays.sort(Object[] a) relies on int compareTo(T o) to sort the array elements, an exception will be thrown if it is passed an array of objects that do not implment Comparable.

Example of trying to use Arrays.sort(Object[] a) with instances of a class that does not implement Comparable.
Contents of Example.java:
import java.util.Arrays;

public class Example {
   public static void main(String[] args) {
      A[] a = new A[]{new A(2), new A(3), new A(5), new A(1), new A(4)};
      System.out.println("before sort: "+Arrays.toString(a));
      Arrays.sort(a);
      System.out.println("after sort:  "+Arrays.toString(a));
   }
}

class A {
   final int i;

   A(int i) {
      this.i = i;
   }
   
   @Override
   public String toString() {
      return "[A "+i+"]";
   }
}
Command to compile Example.java:
javac Example.java
Command to run Example:
java Example
Output from running Example:
before sort: [[A 2], [A 3], [A 5], [A 1], [A 4]]
Exception in thread "main" java.lang.ClassCastException: A cannot be cast to java.lang.Comparable
   at java.util.Arrays.mergeSort(Arrays.java:1144)
   at java.util.Arrays.sort(Arrays.java:1079)
   at Example.main(Example.java:7)

If you want to use Arrays.sort(Object[] a) with your own classes you can mark them as implementing Comparable and define a int compareTo(T o) that is relevant to the specific purpose of the class.

Example of using Arrays.sort(Object[] a) with instances of a class that implements Comparable.
Contents of Example.java:
import java.util.Arrays;

public class Example {
   public static void main(String[] args) {
      A[] a = new A[]{new A(2), new A(3), new A(5), new A(1), new A(4)};
      System.out.println("before sort: "+Arrays.toString(a));
      Arrays.sort(a);
      System.out.println("after sort:  "+Arrays.toString(a));
   }
}

class A implements Comparable<A> {
   final int i;

   A(int i) {
      this.i = i;
   }
   
   @Override
   public int compareTo(A o) {
      if (i<o.i) {
         return -1;
      } else if (i>o.i) {
         return 1;
      } else {
         return 0;
      }
   }
   
   @Override
   public String toString() {
      return "[A "+i+"]";
   }
}
Command to compile Example.java:
javac Example.java
Command to run Example:
java Example
Output from running Example:
before sort: [[A 2], [A 3], [A 5], [A 1], [A 4]]
after sort:  [[A 1], [A 2], [A 3], [A 4], [A 5]]

The java.util.Comparator interface

The Comparator interface defines a int compare(T o1, T o2) method. Implementations of int compare(T o1, T o2) should return a negative integer if the first argument is less than the second; zero if the two arguments are equal; or a positive integer if the first argument is greater than the second.

By creating you own Comparator it is possible to sort instances of a class that does not implement Comparable.

Example of using Arrays.sort(Object[] a, Comparator) to sort instances of a class that does not implement Comparable.
Contents of Example.java:
import java.util.Arrays;
import java.util.Comparator;

public class Example {
   public static void main(String[] args) {
      A[] a = new A[]{new A(2), new A(3), new A(5), new A(1), new A(4)};
      System.out.println("before sort: "+Arrays.toString(a));
      Arrays.sort(a, new AComparator());
      System.out.println("after sort:  "+Arrays.toString(a));
   }
}

class A {
   final int i;

   A(int i) {
      this.i = i;
   }
   
   @Override
   public String toString() {
      return "[A "+i+"]";
   }
}

class AComparator implements Comparator<A> {
   public int compare(A o1, A o2) {
      if (o1.i<o2.i) {
         return -1;
      } else if (o1.i>o2.i) {
         return 1;
      } else {
         return 0;
      }
   }
}
Command to compile Example.java:
javac Example.java
Command to run Example:
java Example
Output from running Example:
before sort: [[A 2], [A 3], [A 5], [A 1], [A 4]]
after sort:  [[A 1], [A 2], [A 3], [A 4], [A 5]]

Sometimes you may be required to sort instances of Comparable using a differant set of criteria than the ones provided by their implementation of int compareTo(T o). By creating you own Comparator you can define your own set of rules for deciding if objects are less than, equal or greater than other instances of the same class.

Example of using a Comparator to sort String objects by length.
Contents of Example.java:
import java.util.Arrays;
import java.util.Comparator;

public class Example {
   public static void main(String[] args) {
      String[] a = {"zebra", "bee", "aardvark", "kangaroo", "deer"};
      System.out.println("before sort: "+Arrays.toString(a));
      Arrays.sort(a, new StringLengthComparator());
      System.out.println("after sort:  "+Arrays.toString(a));
   }
}

class StringLengthComparator implements Comparator<String> {
   public int compare(String o1, String o2) {
      if (o1.length()&lt;o2.length()) {
         return -1;
      } else if (o1.length()&gt;o2.length()) {
         return 1;
      } else {
         return o1.compareTo(o2);
      }
   }
}
Command to compile Example.java:
javac Example.java
Command to run Example:
java Example
Output from running Example:
before sort: [zebra, bee, aardvark, kangaroo, deer]
after sort:  [bee, deer, zebra, aardvark, kangaroo]

See Also