我只是从我的一本书中做一些练习,我很好奇为什么我在eclipse中得到以下错误:
Type mismatch: cannot convert from type DoublyLinkedList.Node<E> to DoublyLinkedList.Node<E>
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
public class DoublyLinkedList<E extends Comparable<E>> implements Iterable<E>{
private int size = 0;
private Node<E> head;
private Node<E> tail;
/** Returns a list iterator object for the list at
* the specified index
*/
public DoublyLinkedList(){
}
private static class Node<E> {
Node<E> next = null;
Node<E> prev = null;
E data;
public Node(E dataItem){
data = dataItem;
}
public Node(E dataItem, Node<E> previous, Node<E> nextNode){
this(dataItem);
prev = previous;
next = nextNode;
}
}
private class MyListIter<E> implements ListIterator<E>{
private Node<E> lastReturned; // a link reference to the last item that was returned
private Node<E> nextItem; // a link reference to the next item in the list
/** The index of the current position */
private int index = 0;
public MyListIter(int pos){
if (pos < 0 || pos > size)
throw new IndexOutOfBoundsException("Invalid index: " + index);
lastReturned = null;
if (pos == size){
index = size;
nextItem = null;
} else { // otherwise we will start at the beginning of the list, and loop until the position in the argument
nextItem = head; // ERROR
for (index = 0; index < pos; index++){
nextItem = nextItem.next; // next item will always reference the list node that is called by the next method
}
}
}
@Override
public void add(E element) {
if (head == null){
Node<E> newNode = new Node<E>(element);
head = newNode; // ERROR
tail = head;
}
}
@Override
public boolean hasNext() {
return nextItem != null; // just checks to make sure there is a node following the current node
}
@Override
public boolean hasPrevious() {
return (nextItem == null && size != 0) || nextItem.prev != null;
}
@Override
public E next() {
if (!hasNext())
throw new NoSuchElementException("There is no node at that location");
lastReturned = nextItem;
nextItem = nextItem.next;
index++;
return lastReturned.data;
}
@Override
public int nextIndex() {
// TODO Auto-generated method stub
return 0;
}
@Override
public E previous() {
if (!hasPrevious())
throw new NoSuchElementException();
if (nextItem == null) // the iterator is at the end of the list
nextItem = tail; // therefore, the nextItem is at the tail, so the previous is the tail. ERROR HERE TOO
else
nextItem = nextItem.prev;
lastReturned = nextItem;
index--;
return lastReturned.data;
}
@Override
public int previousIndex() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void remove() {
// TODO Auto-generated method stub
}
@Override
public void set(E arg0) {
// TODO Auto-generated method stub
}
}
@Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return null;
}
}
我评论了我在3个不同的位置得到错误的确切位置。如果你能提供任何反馈,我将不胜感激。我的书里没有提到这个问题,我四处找了找,似乎真的找不到我想要的答案。
您声明了两种不同的泛型:E
(用于Node
)和E extends Comparable<E>
(用于DoublyLinkedList
)。
这里的主要问题可能是MyListIter
,它是一个非静态内部类,因此自动继承DoublyLinkedList
对E
的定义。因为它继承了E
的定义,所以您应该将其声明为
private class MyListIter implements ListIterator<E>
但是你已经把它变成了MyListIter<E>
,这是将E
重新定义为与DoublyLinkedList
用户的E
不同的东西(隐式E extends Object
与E extends Comparable<E>
)。
我认为 Node
应该按原样工作,因为它是一个嵌套类(与static
关键字),并没有从DoublyLinkedList
继承E
的定义。然而,在这里将其声明为DoublyLinkedList
(private class Node
)的非静态内部类与MyListIter
相同可能是有意义的。
此外,您可能应该允许E
是某种类型的子类型,通过将其声明为E extends Comparable<? super E>
来实现Comparable
。
看起来你得到这个错误,因为你在你的Node
嵌套类中重新定义E
。因为它是一个静态嵌套类,所以它与父类DoublyLinkedList
没有直接关系。将类设置为非静态可能更有意义,这样E
在其内部就继续具有意义。例如:
private class Node {
Node next = null;
Node prev = null;
E data;
...
EDIT:正如ColinD所指出的,MyListIter
同样不应该将E
重新声明为类型参数。像Node
一样改变这个应该可以解决这个问题。
ColinD为右(+1)。
要理解发生了什么,想象一下不使用相同的形式类型参数3次,而是使用E表示DoublyLinkedList, F表示Node, G表示mylisttiter。然后错误消息显示为Type mismatch: cannot convert from type DoublyLinkedList.Node<E> to DoublyLinkedList.Node<G>
。解决方案是ColinD建议的。如果您愿意,您可以将Node<F>
保持静态,并修复所有实例将具有相同的实际类型参数。