While I was trying to solve exercise from generics tutorial Q&A My answers were slightly different
My Answers
public static <T extends Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) //Option1
public static <T extends Comparable<T>>
T max(List<? extends T> list, int begin, int end) //Option2
from quoted answer below
So My question is
Option1 :Would it make any difference if T extends Object & Comparable<? super T>
is replaced with T extends Comparable<? super T>
. Isn't extends Object
implicit ?
Option2 :Would it make any difference if Comparable<? super T>
is replaced with Comparable<T>
? if so How ?
Eclipse code completion creates local variable List<? extends Comparable<? super Comparable<? super T>>> list;
on Ctrl+1 max(list, 1, 10);
which is bit lengthy. How to Define a classes (hierarchy) that extends Comparable<? super T>
, create list and add instances to the list and invoke below method ? Basically I want to know how to invoke max()
after adding class instances A or B
into a list where class B extends A
Write a generic method to find the maximal element in the range [begin, end) of a list.
Answer:
import java.util.*;
public final class Algorithm {
public static <T extends Object & Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) {
T maxElem = list.get(begin);
for (++begin; begin < end; ++begin)
if (maxElem.compareTo(list.get(begin)) < 0)
maxElem = list.get(begin);
return maxElem;
}
}
To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type. If there isn't such a dependency, a generic method should not be used. It is possible to use both generic methods and wildcards in tandem. Here is the method Collections.
Would it make any difference if
Comparable<? super T>
is replaced withComparable<T>
? if so How ?
Remember that Comparables are always consumers, i.e., a Comparable<T>
consumes T
instances, so it should always be preferrable to use Comparable<? super T>
instead of Comparable<T>
(Quoting - PECS). It would make difference in case you are comparing a type whose super class implements a Comparable<SuperType>
. Consider the following code:
class Parent implements Comparable<Parent> {
protected String name;
@Override
public int compareTo(Parent o) {
return this.name.compareTo(o.name);
}
}
class Child extends Parent {
public Child(String name) {
this.name = name;
}
}
Now if you give your type parameter as T extends Comparable<T>
, you won't be able to call that method for List<Child>
, as Child does not implement Comparable<Child>
but Comparable<Parent>
:
public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) {
...
}
public static void main(String[] args) {
List<Child> list = new ArrayList<Child>();
max(list, 0, 2); // Error with current method. Child does not implement Comparable<Child>
}
Hence the type parameter bounds should be T extends Comparable<? super T>
.
Note that, you can't change your Child class to:
class Child extends Parent implements Comparable<Child>
because in that case, Child class would extend from different instantiation of same generic type, which is not allowed.
Would it make any difference if
T extends Object & Comparable<? super T>
is replaced withT extends Comparable<? super T>
. Isn't extends Object implicit ?
Well, there is a difference between the two bounds. In the 1st bound, the erasure of the type parameter is Object
, whereas in the 2nd bound, the erasure is Comparable
.
So, without Object
bound, your code will compile to:
public static Comparable max(List list, int begin, int end)
The issue might come when you are generifying the legacy non-generic code. It's neccessary to give Object
also as upper bound to avoid breaking the Byte Code compatibility. You can read more about it on this link: Angelika Langer - Programming Idioms
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With