Is there a difference between these two common signatures of the "max" function for a collection
Is there a practical difference between these two signatures:
public static <T extends Comparable<? super T>> T max(Collection<T> c)
and
public static <T extends Comparable<T>> T max(Collection<? extends T> c)
I can't think of a single use case where the two are not interchangeable.
Then what is the reason for both? super T and? extends T in the standard max () method in the Java compilations:
public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)
Edit: This question isn't about the difference between <? super T>
and <? extends T>
. The get / put principle is quite clear to me. The question is the difference between these two specific signatures and why the creators of the Java Collections API chose to mix these two signatures for their standard "max" function.
source to share
An example where the two are not interchangeable is:
static class A implements Comparable<Object> {
@Override
public int compareTo(final Object o) {
return 0;
}
}
a list with instances A
works on the first max()
and fails on the second max()
:
error: method max2 in class Generics cannot be applied to given types;
max2(Arrays.asList(new A()));
^
required: Collection<? extends T>
found: List<A>
reason: inference variable T has incompatible bounds
equality constraints: Object
upper bounds: Comparable<T>
where T is a type-variable:
T extends Comparable<T> declared in method <T>max2(Collection<? extends T>)
another example:
static class A {}
static class B extends A implements Comparable<A>{
@Override
public int compareTo(final A o) {
return 0;
}
}
max()
was designed in such a way to make sure that its signature is not changed and all compiled code depending on max()
(code up to Java 5) returning Object
can work, more information in Converting legacy code to use common files .
source to share
Taking a simple example
Animal:
class Animal extends Mammal
Cat:
class Cat extends Animal
Allows you to split the signature.
max(Collection<? extends T> coll)
This is because max must accept a list of animals as well as Cat. Now the rest:
<T extends Comparable<? super T>>
This covers the case where I have an Animal class signature something like this:
Animal extends Mammal implements Comparable<Mammal>
So my comparable object can accept either of its parents and still do a boolean comparison. I know this is not a very practical example, but I hope it makes sense.
source to share
Then what is the reason for both? super T and? extends T in the standard max () method in the Java compilations:
Just to make the most of the maximum possible operation, given that the operations it will perform on this collection and their elements are just iterator().next
and compareTo
. In other words, it declares the weakest constraints required for its type of arguments, which still allows its code to compile.
source to share