Search code examples
javacomparable

How to Implement the Comparable Interface and Why Should We Implement It


What is the best way to override the compareTo() method of the Comparable Interface? Additionally, why would we ever need to implement the Comparable Interface when we can write our own compareTo() method without the implementation. Take the following Seat class for example:

public class Seat {
        private final String seatNumber;
        private double price;

        public Seat(String seatNumber, double price) {
            this.seatNumber = seatNumber;
            this.price = price;
        }

        public int compareTo(Seat seat) {
            return this.seatNumber.compareToIgnoreCase(seat.getSeatNumber());
        }
}

The above works even though we did not implement the Comparable Interface, so why should we ever implement it?


Solution

  • why would we ever need to implement the Comparable Interface when we can write our own compareTo() method without the implementation

    Take for example Collections.sort. The signature is

    public static <T extends Comparable<? super T>> void sort(List<T> var0)
    

    The generic type parameter means that we can only sort lists of things which are comparable to themselves (or subtypes). For example, we can sort a list of strings because String implements Comparable<String>. That is, a string knows whether it should naturally fall before or after another string.

    Without an interface to define this constraint, this method could not exist.


    What is the best way to override the compareTo() method of the Comparable Interface?

    That entirely depends on the class you're working with. If it does not have a clear natural ordering then maybe you shouldn't. A seat could be sorted either by number or by price. It doesn't necessarily make sense to choose one arbitrarily.

    For that reason, often methods such as the above Collections.sort will provide a second signature which takes a Comparator:

    public static <T> void sort(List<T> var0, Comparator<? super T> var1)
    

    This means that we don't have to arbitrarily define whether a seat is naturally ordered by number or price. We can have one piece of code which uses one comparator to sort by price, and another totally separate piece of code which uses another comparator to sort by seat number.

    One advantage of implementing Comparable is that you don't need to necessarily expose internal class details to determine an instances ordering as you would with a Comparator.