I have a three class: 1.class Algorithm
having max()
finding maximum value in a Collection
:
public class Algorithm {
public static <T extends Comparable<T>> T max(Collection<? extends T> coll) {
T max = coll.iterator().next();
for (T elm : coll) {
if (max.compareTo(elm) < 0)
max = elm;
}
return max;
}
}
2.Class Fruit
:
public class Fruit implements Comparable<Fruit> {
private String name;
private int size;
public Fruit(String name, int size) {
this.name = name;
this.size = size;
}
public int compareTo(Fruit that) {
if (size < that.size)
return -1;
else if (size == that.size)
return 0;
else
return 1;
}
}
3.class Apple
extending Fruit
:
public class Apple extends Fruit {
public Apple(int size) {
super("Apple", size);
}
}
Now the question is this:
public class Main
{
public static void main(String[] args) {
Apple a1 = new Apple(10);
Apple a2 = new Apple(34);
List<Apple> apples = Arrays.<Apple>asList(a1, a2);
System.out.println(Collections.max(apples).size);
}
}
According to this post Java - Syntax Question: What is I should wrote it this way: public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)
. But it is working fine now.Why? Class Apple
does not implement Comparable<Apple>
and there is no super
.
[UPDATE]
Java Generics and Collections Book says:
Without the
super
wildcard, finding the maximum of aList<Apple>
would be illegal, even though finding the maximum of aList<Fruit>
is permitted.
Suppose we changed the max
method to this:
<T extends Comparable<T>> T max(Collection<? extends T> coll)
You would not be able to get the max
of a List<Apple>
because Apple
does not implement Comparable<Apple>
, it implements Comparable<Fruit>
. But you and I know perfectly well that an Apple
knows how to compare itself to another Fruit
because it inherited that functionality.
We fix the problem by changing the declaration of max
to this:
<T extends Comparable<? super T>> T max(Collection<? extends T> coll)
This means that we accept any class T
such that:
T implements Comparable<T>
, or...T implements Comparable<X>
for some X
such that X
is a super class of T
In order to find the max
, we must be sure that any instance of T
can safely accept another instance of T
as an argument to its compare
method.
In the first scenario, it is obvious that any instance of T
can safely accept another instance of T
as an argument to its compare(T)
method.
In the second scenario, any instance of T
can safely accept another instance of T
as an argument to its compare(X)
method because all instances of T
are also instances of X
.
Your example illustrates the second scenario, where T
corresponds to Apple
and X
corresponds to Fruit
.