Search code examples
javacollectionscomparatorcomparable

Split off logic in methods when custom Comparator is provided or elements implements Comparable?


What is The best practice to split off logic in methods , who will work with Comparable elements, or specific Comparator is provided at creation time, depending on which constructor of the class is used? Example:

public class MinMax<E> {

private final Comparator<? super E> comparator;
private final boolean isSpecificComparatorProvided;

public MinMax() {
    this.comparator = null;
    this.isSpecificComparatorProvided = false;
    ........;
}

public MinMax(Comparator<? super E> comparator) {
    this.comparator = comparator;
    this.isSpecificComparatorProvided = true;
    ........;
}

private boolean isBigOrEqual(E e1, E e2) {
    if (isSpecificComparatorProvided) {
        Comparator<? super E> cpr = comparator;
        int cmpr = cpr.compare(e1, e2);
        return cmpr > -1;
    } else {
        @SuppressWarnings("unchecked")
        Comparable<? super E> e1Comparable = (Comparable<? super E>) e1;
        int cmprTo = e1Comparable.compareTo(e2);
        return cmprTo > -1;
    }
}

}

Do I have allways check for specific comparator in method isBigOrEqual()? Also is the cast to Comparable needed when NO specific Comparator is provided? Is there a other way ?


Solution

  • Probably the simplest way of dealing with this is to only implement the case for a Comparator, and then when you're not passed a Comparator, write one that just works on Comparable. (In Java 8, this is just Comparator.naturalOrder().)

    new Comparator<T> {
      @Override public int compare(T a, T b) {
        return a.compareTo(b);
      }
    };
    

    TreeMap doesn't do this for performance reasons, but it's simpler to do it this way.