(If this is a duplicate please point me to the right answer! I searched and read several (>5) related questions but none seemed on the mark. Also looked at the Generics FAQ and other sources...)
It is apparently proper practice that when a collection class takes a comparator it should have the type Comparator<? super T>
for your parameterized type T
. And you can see that lots of places, e.g., TreeMap
. Okay.
My problem is working with Comparator.naturalOrder()
which is parameterized on T extends Comparable<? super T>
but returns a Comparator<T>
. I'm trying to have a field in my collection class that holds either the user-specified comparator or the Comparator.naturalOrder
comparator.
I can't get it to work. My questions, all related, are:
- How is
Comparator.naturalOrder
properly used?- And can I do what I want which is have a field where I store either a user-supplied comparator or the
naturalOrder
comparator?
- And can I do what I want which is have a field where I store either a user-supplied comparator or the
- Given that most collection classes (in the framework) are parameterized on
T
notT implements Comparable<? super T>
, so that's the design pattern chosen, how isnaturalOrder
useful since it requires the latter bounded wildcard, not the unconstrained type parameter?
Thanks!
Here follows the actual examples with compiler errors:
So: If I have code like this in some class where T has no bounds (as in all existing collection classes):
class Foo<T> {
private Comparator<? super T> comparator;
public void someMethod(Comparator<? super T> comparator)
{
this.comparator = comparator; // no compile error
this.comparator = Comparator.naturalOrder(); // incompatible types
}
}
with this error:
Error:(331, 50) java: incompatible types: inferred type does not conform to upper bound(s)
inferred: T
upper bound(s): java.lang.Comparable<? super T>
So if I decide to forgo the advantages of ? super T
then I have:
class Foo<T> {
private Comparator<T> comparator;
public void someMethod(ComparatorT> comparator)
{
this.comparator = comparator; // no compile error
this.comparator = Comparator.naturalOrder(); // incompatible types
}
}
where I have
Error:(nnn, 50) java: incompatible types: inference variable T has incompatible bounds
equality constraints: T
upper bounds: java.lang.Comparable<? super T>