2011-08-21 128 views
1

我只是做一些練習,從我的書之一,我很好奇爲什麼我收到以下錯誤在日食:無法將節點<E>轉換成節點<E>?

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個不同的位置得到錯誤。如果你能提供任何反饋,我會很感激。我的書沒有解決它,我已經搜索過,並且看起來無法得到我正在尋找的答案。

回答

5

您已經定義了兩個不同的泛型類型:E(爲Node)和E extends Comparable<E>(用於DoublyLinkedList)。

這裏的主要問題可能是MyListIter,這是一個非靜態的內部類,因此它會自動繼承EDoublyLinkedList的定義。因爲它繼承了E的定義,你應該只被聲明爲

private class MyListIter implements ListIterator<E> 

,但你做了它MyListIter<E>,這是重新定義E到的東西比EDoublyLinkedList用戶不同(隱式E extends ObjectE extends Comparable<E>) 。

認爲Node將正常運行,是因爲它是一個嵌套類(與static關鍵字),並沒有從DoublyLinkedList繼承E定義。但是,它很可能是有意義這裏將其聲明爲一個非靜態內部類的DoublyLinkedList(​​)一樣MyListIter

此外,你應該讓E是一個類型,它是某種類型的通過聲明爲E extends Comparable<? super E>實現Comparable亞型

+0

+1好點關於'E extends Comparable ' –

+0

哇。我永遠不會知道。我認爲這固定了一切。這本書寫得很糟糕。我的印象是,如果DoublyLinkedList類型爲,則該類別中的所有內容也應該是,使它們全部屬於同一類型。但我猜它不是? – TMGunter

+2

@TMGunter:如果聲明瞭一個不帶'static'關鍵字的內部類,則該內部類的所有實例都必須屬於包含類的特定_instance_。因此,它們自動訪問爲包含類聲明的泛型類型(在這種情況下爲'E')。我實際上不確定'Node'在這裏是一個問題,因爲它有'static'關鍵字,因此它是一個嵌套類,它不會繼承'E'的定義。 'MyListIter'在這裏可能是真正的問題,因爲它繼承了'E'的定義,但也聲明瞭它自己的(衝突的)定義。 – ColinD

3

看起來你得到這個錯誤是因爲你在你的Node嵌套類中重新定義了E。由於它是一個靜態嵌套類,它與父類DoublyLinkedList沒有直接關係。讓這個類非靜態變得更有意義,這樣E就繼續有它的意義。例如:

private class Node { 

Node next = null; 
Node prev = null; 
E data; 

... 

編輯:如ColinD指出,MyListIter應同樣不重新聲明E作爲類型參數。改變這個像Node應該解決這個問題。

+0

當我這樣做,它抱怨不是一般的我的節點構造和說,「型DoublyLinkedList .Node不是通用的;它不能與參數參數」 – TMGunter

+0

你一定要改變這一切'節點'類型到'Node'? –

+0

是的。節點現在是類型節點。我還用科林的建議使E成爲了一個子類型。我的書完全沒有涉及,但我想我理解它的含義。我必須查看它。它使我更加有意義的是,讓Node成爲一個私有的嵌套類,並移除它的靜態屬性。我試圖追蹤我的書,我認爲它的教學效果並不好。 – TMGunter

1

ColinD是對的(+1)。

要了解發生了什麼事情,試想沒有使用相同的形式類型參數的3倍,而E代表DoublyLinkedList,F爲節點和G爲MyListIter。然後錯誤信息會說Type mismatch: cannot convert from type DoublyLinkedList.Node<E> to DoublyLinkedList.Node<G>。 ColinD建議的解決方案是。如果你願意,你可以離開Node<F>靜態,修復所有實例將具有相同的實際類型參數。

+0

所以我真的可以定義任何類型的靜態類「節點」我真的想要?當我在頂級類中使用對節點的引用時,即使節點被定義爲節點,它將繼承父類的類型「E」?這就是我正在收集的內容。如果我不使它成爲一個靜態的內部類,我不應該使用類型參數定義節點,因爲類型「E」將從最頂級的類繼承而來。 – TMGunter

+0

@TMGunter:是的,是的。 – DaveFar

+0

爲了清楚起見:在'public class DoublyLinkedList head;',就像例如'private Node head;'或'private List head;'一樣。就像List的正式類型參數完全獨立於你的'E'並且可能是'F'或其他任何東西一樣,''private static class Node '的形式類型參數是。這就是爲什麼我建議使用不同的字母,以避免混淆。 – DaveFar

相關問題