0

I am having hard time understanding the best way to use generic type parameters.

Consider a priority queue implementation that implements an interface and requires all elements to be comparable of its type. The class has a constructor of with input type collection which provides initial elements. Here are a few alternatives. Can you explain differences? And provide the most general way of such declaration?

public class HeapMinPQ<E extends Comparable<E>> implements MinPQ<E> {
     ...
     public HeapMinPQ( Collection<? extends Comparable<E>> source) {
     ...
     }
}


public class HeapMinPQ<E extends Comparable<E>> implements MinPQ<E> {
     ...
     public HeapMinPQ( Collection<? extends E> source) {
     ...
     }
}


public class HeapMinPQ<E extends Comparable<? super E>> implements MinPQ<E> {
     ...
     public HeapMinPQ( Collection<? extends Comparable<E>> source) {
     ...
     }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
user2259824
  • 135
  • 8
  • I am not offended. It is not a homework. I am studying for an interview. My attempt to implement heap based priority queue. – user2259824 Jun 28 '16 at 00:08
  • relevant: http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super & the reason why the most generic type is `E extends Comparable super E>`. – zapl Jun 28 '16 at 00:45

1 Answers1

1

Your constructors should not use Collection<? extends E> but Collection<E> as the type of the parameter. Also, your examples are incomplete; they don't show how the arguments are intended to be used.

In the first case, source contains elements guaranteed to be of type capture ? of Comparable<E>. The base type might or might not be compatible with E. So it wouldn't necessarily be safe to extract an element from source and use it against an E instance.

In the second, source contains elements guaranteed to be of type capture ? of E, which means the base type is compatible with E. It would be usable against an instance of E as long as the particular subtype doesn't matter.

In the third, the class time is weird. It says that E is comparable to its supertypes, which is not generally true for comparable types. It is likely to cause you heartache, and also there's no guarantee that the capture ? of Comparable<E> base type of source will work to compare to E or be otherwise compatible with E.

Generally you don't want to mess with captures of E in a type generic over E, but the full details are complex. I suggest Angelika Langer's excellent site, http://www.angelikalanger.com/, particularly http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html, to obtain more knowledge, as well as the articles on Developerworks and in the Oracle Tutorials.

Lew Bloch
  • 3,364
  • 1
  • 16
  • 10
  • One more detail please; does the second case guarantee that all collection elements are comparable with each other? Since I declared E to be that way in class declaration. – user2259824 Jun 28 '16 at 01:00