public interface Comparable<T> {
public int compareTo(T o);
}
The interface is a little non-intuitive because the method compareTo does not take a Comparable
Consider a algorithm to find the max item, with input being a list of items, each implementing Comparable :
public static<T> Comparable<T> max(Collection<Comparable<T>> coll){
Iterator<Comparable<T>> iterator = coll.iterator();
Comparable<T> maxElement = iterator.next();
while(iterator.hasNext()){
Comparable<T> nextElem = iterator.next();
if (nextElem.compareTo((T)maxElement) > 0 ){
maxElement = nextElem;
}
}
return maxElement;
}
Since the input is a Comparable type, the only way to invoke a compareTo method inside this algorithm is to cast from Comparable<T> to the java type, which defeats the use of generics, a better way to get it to work is to declare the type this way - <T extends Comparable<T>> , or even better this way: <T extends Comparable<? super T>>
public static<T extends Comparable<T>> T max(Collection<? extends T> coll){
Iterator<? extends T> iterator = coll.iterator();
T maxElement = iterator.next();
while(iterator.hasNext()){
T nextElem = iterator.next();
if (nextElem.compareTo(maxElement) > 0 ){
maxElement = nextElem;
}
}
return maxElement;
}
@Test
public void testMaxForASmallListOfIntegers(){
List<Integer> arr =Arrays.asList(5,3,10,2000,15,9,2,1);
assertThat(max(arr), is(2000));
}
This time around the generic type declaration is <T extends Comparable<T>>, which says that T implements Comparable, and the API from a client perspective is also clean as demonstrated in the accompanying test.