java.util.Comparator.naturalOrder takes a <T extends Comparable<? super T>> and returns a Comparator<T> - why?

This compiles:

import java.util.*;

class Foo<T extends Comparable<? super T>> {

    private Comparator<T> comparator;

    public void someMethod(Comparator<T> comparator)
    {
       this.comparator = comparator;                  // no compile error
       this.comparator = Comparator.<T>naturalOrder(); // <T> is optional, compiler can infer
    }
}

The simplest way to think about it is this: you are trying to use type T with the Comparator interface, which imposes certain requirements on it (in particular it has that fancy recursive requirement that T must implement Comparable interface). You do not impose such requirement when genericising (?) your class, so compiler is not happy. Your requirements on T must be as strong as the class that you are using it with.

You are confused about what natural ordering method does. It just takes a class which implements Comparable and creates the default Comparator for it. No way around it -- you can't create a Comparator for something that is not Comparable.

You want TreeMap to require Comparable, but you can't, because it is a valid case to use something that is not comparable, as long as you have provided a Comparator. So TreeMap ends up not enforcing Comparable and just casts explicitly at runtime (and throws an exception).


I guess you have to implement Comparable to use Comparator.naturalOrder() in your class Foo in your example. You must have a method compareTo(Object o), that method is the one that implements the natural order so you don't need to store it in a variable.

I think you can use comparators in a class that doesn't implements the comparable interface at least in Java 8, so they don't implements compareTo(Object o) but you have to implement this

@FunctionalInterface
public interface Comparator<T>

This is from the Java 8 API

A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.

A way of implementing and initialising it:

private  Comparator<Operario> ComparatorOperario =
    (o, p)-> o.getNombre().compareTo(p.getNombre());

then you can have getters and setters for this variable so you can change the way of ordering

note that the class Operario doesn't implements Comparable, it uses a Comparator<Operario> that compares 2 attributes from the class Operario, in this case two Strings.