I am having an issue combining generics, implements
, and inner classes.
I am creating a LinkedBinaryHeap
class which contains an inner class. This inner class is the generic HeapNode
which extends the generic Node
class I created; it just adds a variable and methods for a key/priority.
In LinkedBinaryHeap
I create a generic LinkedList
to store HeapNode
s.
I am assuming the generic data being stored extends Comparable
class.
Here is a layout of what stores what:
BinaryHeap->LinkedList(Nodes)->HeapNode(extends Node)->DATA,KEY
My issue is that when declaring the LinkedList
:
LinkedList<HeapNode> heap;
eclipse underlines HeapNode
and gives me the error:
Bound mismatch: The type LinkedBinaryHeap.HeapNode is not a valid substitute for the bounded parameter > of the type LinkedList
I think the error is telling me that HeapNode
must implement the Comparable
, however my Node
class implements Comparable
, so that is taken care of, correct?
I have tried all sorts of different things, but nothing seems to work, the below code is the closest I came. Note that I have tried leaving implements Comparable Node<T>
off the HeapNode
inner class, and it changes nothing.
Code:
LinkedBinaryHeap.java:
public class LinkedBinaryHeap<E extends Comparable<E>> {
private LinkedList<HeapNode> heap;
public LinkedBinaryHeap(){
heap = new LinkedList<HeapNode>();
}
/* INNER CLASS DECLARATION. */
private class HeapNode extends Node<E> implements Comparable<Node<E>>{
int key;
public HeapNode(int key, E data){
super(data);
this.key = key;
}
public int getKey(){
return key;
}
public void setKey(int key){
this.key = key;
}
}
}
Node.java:
public class Node<T extends Comparable<T>> implements Comparable<Node<T>>{
protected T data;
protected Node<T> next;
protected Node<T> previous;
public Node(T data){
next = null;
previous = null;
this.data = data;
}
/* Some other methods left out here. */
public int compareTo(Node<T> node) {
return data.compareTo(node.getData());
}
}
LinkedList.java:
public class LinkedList<T extends Comparable<T>> implements Comparable<LinkedList<T>>{
private Node<T> head;
private Node<T> tail;
private int size;
public LinkedList(){
head = null;
tail = null;
size = 0;
}
/* Other methods left out. */
public int compareTo(LinkedList<T> list){
// does stuff.
}
}
As per your definitions:
HeapNode
is a subtype ofNode<E>
butimplements Comparable<Node<E>>
LinkedList
requires a type argument such thatT implements Comparable<T>
- i.e. a
LinkedList<HeapNode>
requires thatHeapNode implements Comparable<HeapNode>
- which it does not (from (1), above, it
implements Comparable<Node<E>>
)
So the two are not compatible.
You need, in LinkedList
, to express the node type as a type parameter, bounded appropriately, and the node type's component type parameter as well, also bounded appropriately:
public class LinkedList<N extends Node<E>,
E extends Comparable<E>>
implements Comparable<LinkedList<N, E>>{
private N head;
private N tail;
private int size;
...
Now your LinkedBinaryHeap
needs to adjust it's use of LinkedList
:
public class LinkedBinaryHeap<E extends Comparable<E>> {
private LinkedList<HeapNode, E> heap;
public LinkedBinaryHeap(){
heap = new LinkedList<HeapNode, E>();
}
That should now compile. Whether it achieves your goals of comparing everything to everything else is harder to say!
LinkedList requires that T implements Comparable. HeapNode implements Comparable<Node<E>>
. HeapNode != Node so it doesn't satisfy the type bound. Change LinkedList's declaration to T extends Comparable<? super T>
. This is fine, type-wise: HeapNode is declaring that it can compare itself with any Node or subtype of Node. Of course, this means that HeapNode needs to override compareTo
, but you're kind of stuck there, what with Node already implementing Comparable.
Edit: as comments point out, this answer is wrong, and not worth fixing because there's a right answer. Let it stay for posterity as a lesson in...something. How I'm not as knowledgeable on generics as I'd like to be, maybe.
来源:https://stackoverflow.com/questions/28653444/java-issue-combining-generics-inner-class-and-implements