In this task, we will look at a particularly useful interface class from the Java API called java.util.Comparable. This interface specifies an API to compare two object instances of a class with each other while the specifics of the comparison are up to the developer. A very similar interface is java.lang.Comparator. While a class implementing Comparator will take two object instances and compare them to each other, the Comparable will take a single object instance and compare it to itself. We will look at the Comparator interface in a later question.
Both interfaces are very popular in the Java API and used a lot, particularly for collection classes and methods. Consider for example the static method Collections.sort from the java.util.Collections class. It will take a list of specific objects and a corresponding Comparator and sorts them according to the ordering defined by the Comparator's specific implementation. Have a look at the corresponding Java API for more information.
Note
Generics are heavily used for collection methods which we have not covered in detail. Simply swap the generic parameter T for a class you know such as Integer if you have trouble understanding something. Integer also implements the Comparable interface.
For example, we have a class Car which has a speed parameter. We want to make the Car comparable to other Cars based on that speed parameter. So we go ahead and implement the interface Comparable in our Car class by adding it to the class signature.
Note
Remember to use the keyword implements for interfaces in your class signature rather than extends which you would use for sub-classing.
The Comparable API provides an abstract method compareTo, which takes one argument of the same data type as the class implementing the interface. So when we override this method in our implementation, its signature would be:
public int compareTo(Car that)
Let us now compare a Car instance A with a speed of 100 mph to a Car instance B with a speed of 120 mph. We then call the compareTo method on the instance of A and pass in B as method argument. We then print the result.
Car A = new Car(100); Car B = new Car(120); System.out.println(A.compareTo(B));
The Java API states that the return value is
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
In our example, the return result would therefore be a negative value. Usually, -1.
If we would call:
System.out.println(B.compareTo(A));
The return value would be positive, usually +1. If both cars had the same speed, the return value would be zero.
Each class implementing this interface has to override this abstract method and follow its specified contract as described for the return value. Have a look at the corresponding Java API for more information.
Note
The cases where the given parameter is null or the exact same instance as the instance this method is called on, also need to be considered.
In this exercise, implement the comparison for the Car class. Create a class Car and implement the Comparable interface for this class.
Define a private instance member speed of type integer and indicating the current speed and another private final instance member maxSpeed indicating the maximum speed of the car. Also implement the following API:
- public Car(int maxSpeed)
- Class constructor which assigns the maximum speed of the car.
The maxSpeed parameter must not be negative. Add expected error handling.
- public int getSpeed()
- Accessor for the current speed of the car.
- public void gas(int delta)
- Changes the current speed of the car. The given parameter can be positive and negative
for acceleration and deceleration.
The car should not go faster than the maximum speed even if you keep hitting the gas. The same is true for deceleration. The speed should never be smaller than zero even if you keep your foot on the break.
- public int compareTo(Car that)
- Compares the speed of the given car to this instance according to the specification of the implemented interface.
Note
The documentation states: Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException ...
An automated test has been created for this exercise: CarTest.java.