Java

TOPIC – THE COMPARABLE INTERFACE

 

 

LESSON NOTE

 

 

THE COMPARABLE INTERFACE

 

Classes that implement the Comparable interface allow us to compare two of their objects to one another and determine which object comes first and which object comes second. 

 

CRITERIA FOR COMPARISION

 

The criteria that we use to compare two objects is up to us.  Often, we think of this as ‘which object is smaller and which object is larger?’.  However, this is not always the case.

 

For example, if we have a Cube class that implements the Comparable interface, we may want to compare two cube objects based on their volume.  So the cube with the smaller volume would come first and the cube with the larger volume would come second. 

 

However, we might not care about cube sizes and may instead want to compare these two cubes based on their distance from the origin.  So, the cube closest to the origin would come first and the cube further from the origin would come second.

 

Note that no matter the comparing criteria, the object that comes first is considered the smaller object and the object that comes second is the larger object.

 

WHY IS COMPARABLE USEFUL?

 

It turns out that if you can compare two objects to order them, you can apply that process to many objects and also order them.  So we can sort many objects based on some criteria.

An array of objects that are comparable can be sorted using Arrays.sort().

 

HOW TO SORT?

 

It turns out that once Comparable is implemented, then Java has already done all of the work for you. 

 

Step 1 – We make our class implement Comparable (more on this below)

 

Step 2 - We then place our objects inside an array ar.

 

Step 3 - We then use Arrays.sort(ar).

 

Done!  Now the entire array is sorted based on the comparing criteria.

 

HOW TO IMPLEMENT COMPARABLE

 

Once a class implements Comparable, you are forced to implement the following method:

 

public int comparesTo(Object o)

{}

 

The job of this method is simple.  It is to determine if the object that you are currently inside (the this object) is smaller, equal or greater than Object o.

 

If the this object is smaller than o, then we return -1 (or we could return any negative number).

 

If the this object is equal to o, then we return 0.

 

If the this object is greater than o, then we return 1 (or we could return any positive number).

 


EXAMPLE

 

PART 1

 

Before we get to using Comparable, let’s first consider the Prism class below.

 

The class simply has three int data fields that represents the prism’s width, height and depth.  It has an vol() that calculates the volume and returns it.  It also has a toString method that simply outputs the cube’s

 

public class Prism

{

     public int w;  //width

     public int h;  //height

     public int d;  //depth

    

     public Prism (int w, int h, int d)

     {

         this.w = w;

         this.h = h;

         this.d = d;

     }

    

     public int vol()

     {

         return w * h * d;

     }

    

     public String toString()

     {

         return w + "x" + h + "x" + d + "=" + vol();

     }

}

 

 

PART 2

 

We can now use the Prism class above in a main. 

 

public class PrismTester

{

     public static void main(String[] args)

     {

         Prism[] ar = new Prism[5];

         for(int i=0; i<ar.length; i++)

         {

              int width = (int)(10 * Math.random() + 1);

              int height = (int)(10 * Math.random() + 1);

              int depth = (int)(10 * Math.random() + 1);

              ar[i] = new Prism(width, height, depth));

         }

         System.out.println(Arrays.toString(ar));

     }

}

 

Below is example output from the above code:

 

[8x5x10=400, 8x9x7=504, 4x1x3=12, 1x2x1=2, 6x9x9=486]

 

Notice the last number after the equal is the volume for the prism.

 

 

PART 3

 

So we now want to be able to sort the Prism objects in the ArrayList.  We can do this in a painful way by implementing our own sorting algorithm.  Or, we can use Comparable!

 

First, the line

 

   public class Prism

 

is changed to

 

   public class Prism implements Comparable

 

Next, we need to add the required method.  We can do this by hovering over the class name and choosing Add unimplemented methods.  Or we can just type in the method header ourselves. 

 

     @Override

     public int compareTo(Object o)

     {

          Prism other = (Prism)o;

         if (this.vol() < other.vol())

         {

              return -1;

         }

         else if (this.vol() == other.vol())

         {

              return 0;

         }

         else

         {

              return 1;

         }

     }

 

The first line inside the method type casts the Object o into a Prism object named other.  The rest of the code compares the this object to the other object.

 

If this’s volume is less than other’s volume, return -1. 

 

If this’s volume is equal to other’s volume, return 0.

 

If this’s volume is greater than other’s volume, return 1.

 

Done!

 

 

PART 4

 

We can now simply use Collections.sort inside of our main function to sort the ArrayList.  We have only added two new lines at the bottom of the code below.

 

public class PrismTester

{

     public static void main(String[] args)

     {

         Prism[] ar = new Prism[5];

         for(int i=0; i<ar.length; i++)

         {

              int width = (int)(10 * Math.random() + 1);

              int height = (int)(10 * Math.random() + 1);

              int depth = (int)(10 * Math.random() + 1);

              ar[i] = new Prism(width, height, depth));

         }

         System.out.println(Arrays.toString(ar));

         Arrays.sort(ar);

         System.out.println(Arrays.toString(ar));

     }

}

 

Here is example output from the code above:

 

[3x7x4=84, 4x7x9=252, 1x3x2=6, 4x5x4=80, 6x7x10=420]

[1x3x2=6, 4x5x4=80, 3x7x4=84, 4x7x9=252, 6x7x10=420]

 

As you can see, the Prism objects are now sorted by their volume.