The Java Comparable interface – Automatically sort collections

by

in

In this post, we will explore how to use the Java comparable interface to automatically sort collections of any classes. We will use the Java Collections from the util library as an example.

Why interfaces are so important?

Java interfaces are one of the most powerful features of the object oriented programming language. When a class implements an interface, it behaves as a programming contract that is guaranteed to be fulfilled.

In other words, if a class implements an interface, then we can rely that certain functionality is available with instances of this class, and every other class that implements that interface.

This allows us to reuse functionalities built into Java and other 3rd party libraries. For example, if you implement the Comparable interface then you can take advantage of Java functionalities such as sorting.

How to automatically sort a collection of Objects?

We will explore interfaces in more detail in a later post. For now, let us take the Collections utility from Java as an example. The sort method accepts a list as an argument. If the list elements implement the comparable interface, then we have automatically achieved compatibility with the “sort” functionality.

Below is the class Car, which has three members. The car brand, the car model and the maximum speed. For the sake of simplicity, we will just use the maximum speed for comparison. The requirement for the comparable interface is only one method, the “compareTo” method. When comparing instance A to B, the following output is expected:

  • If A is more than B, then return a positive number
  • If is less than B, then return a negative number
  • If A and B are considered equal, then return zero.

Below is an example implementation of the comparable interface.

package com.nullbeans.java.basics;

/**
 * Copyright: nullbeans.com
 *
 * Use at your own risk.
 * If you would like to copy this code to your project or website, please go ahead, as long as this copyright notice is kept attached to the file.
 */


public class Car implements Comparable<Car> {

    private String brand;

    private String model;

    private int maxSpeed;

    public Car(){
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public int compareTo(Car car) {
        if(car.maxSpeed<this.maxSpeed){
            return 1;
        }else if(car.maxSpeed>this.maxSpeed){
            return -1;
        }else {
            return 0;
        }
    }

    @Override
    public String toString() {
        return "\nCar{" +
                "brand='" + brand + '\'' +
                ", model='" + model + '\'' +
                ", maxSpeed=" + maxSpeed +
                '}';
    }
}


Now, let us put the theory to the test. Below is a test that initializes four different instances of the Car class and we will attempt to sort them using the Collections util from Java.

package com.nullbeans.nullbeansserver;

/**
 * Copyright: nullbeans.com
 *
 * Use at your own risk.
 * If you would like to copy this code to your project or website, please go ahead, as long as this copyright notice is kept attached to the file.
 */

import com.nullbeans.java.basics.Car;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ComparableTest {

    private static final Logger logger = LoggerFactory.getLogger(ComparableTest.class);

    @Test
    public void testSort(){

        //Initialize test data
        Car car1 = new Car();
        car1.setBrand("GrandeAuto");
        car1.setModel("Speeder");
        car1.setMaxSpeed(230);

        Car car2 = new Car();
        car2.setBrand("GrandeAuto");
        car2.setModel("Van");
        car2.setMaxSpeed(160);

        Car car3 = new Car();
        car3.setBrand("GrandeAuto");
        car3.setModel("Ultra Speedster");
        car3.setMaxSpeed(280);

        Car car4 = new Car();
        car4.setBrand("GrandeAuto");
        car4.setModel("Comfort");
        car4.setMaxSpeed(160);

        //Generate
        List<Car> cars = Arrays.asList(car1, car2, car3, car4);

        //print current order
        logger.info("Current order is: {}", cars);

        //Use the java utils for sorting
        Collections.sort(cars);

        //print sorted order of cars
        logger.info("Sorted order is: {}", cars);
    }
}

The following output was obtained from the log statements:

2018-12-10 22:34:30,636 INFO  [main] com.nullbeans.nullbeansserver.ComparableTest: Current order is: [
Car{brand='GrandeAuto', model='Speeder', maxSpeed=230}, 
Car{brand='GrandeAuto', model='Van', maxSpeed=160}, 
Car{brand='GrandeAuto', model='Ultra Speedster', maxSpeed=280}, 
Car{brand='GrandeAuto', model='Comfort', maxSpeed=160}]

2018-12-10 22:34:30,642 INFO  [main] com.nullbeans.nullbeansserver.ComparableTest: 
 Sorted order is: [
Car{brand='GrandeAuto', model='Van', maxSpeed=160}, 
Car{brand='GrandeAuto', model='Comfort', maxSpeed=160}, 
Car{brand='GrandeAuto', model='Speeder', maxSpeed=230}, 
Car{brand='GrandeAuto', model='Ultra Speedster', maxSpeed=280}]


Notice that the first log statement printed the cars with the order they were at in the original list. The second list had the cars sorted by their maximum speed. We didn’t need to implement any sorting algorithm. We only needed to define which car is “more than” the other one, and then we took advantage of the built in Java functionality to sort the list 😉