2012-06-09 32 views
0

任何人都可以解釋爲什麼我得到這個錯誤嗎?當嘗試在Java中實現Iterable時使用泛型時出錯

這裏是一個堆棧類我用一個雙向鏈表實現:

import java.util.Iterator; 

public class Stack<Item> implements Iterable<Item>{ 

private Node first; 
private int N; 

private class Node{ 
    private Node next; 
    private Node prev; 
    private Item item; 
} 

public Iterator<Item> iterator(){ 
    return new ReverseIterator<Item>(); 
}  

private class ReverseIterator<Item> implements Iterator<Item>{ 
    private Node x; 

    private ReverseIterator(){ 
     if (first != null) 
      x = first.prev; 
    } 

    public boolean hasNext(){ 
     return x != null; 
    } 

    public Item next(){ 
     Item i = x.item; 
     x = x.prev; 
     return i; 
    } 

    public void remove(){ 
    } 
} 

public void push(Item i){ 
    if (isEmpty()){ 
     first = new Node(); 
     first.item = i; 
     first.next = first; 
     first.prev = first; 
    } 
    else{ 
     Node x = new Node(); 
     x.item = i; 
     x.next = first; 
     x.prev = first.prev; 
     first.prev.next = x; 
     first.prev = x; 
    } 
    N++; 
} 

public Item pop(){ 
    assert !isEmpty() : "Stack is empty"; 

    Item i = first.prev.item; 
    if (N == 1) 
     first = null; 
    else{ 
     first.prev.prev.next = first; 
     first.prev = first.prev.prev; 
    } 

    N--;  
    return i; 
} 

public boolean isEmpty(){ 
    return N == 0; 
} 

public int size(){ 
    return N; 
} 

public static void main(String[] args){ 

} 
} 

編譯器說,有一個在Item i = x.item;錯誤,預期的項目,發現項目。解決方案是用ReverseIterator替換ReverseIterator<Item>。有人可以解釋爲什麼我通過加入<Item>得到錯誤嗎?

感謝

回答

4

只是因爲你的類型變量(Item)使用相同的名稱並不意味着它代表了同泛型類型。

如果要聲明一個嵌套類N<T>,泛型類C<T>內,從C<T>T有效地從N<T>身體隱藏。這與宣佈一個名爲x的類級別字段並在該類中聲明方法參數(也稱爲x)的原理完全相同。你最內層的聲明範圍隱藏了外部的任何東西。

如果ReverseIterator是一個靜態嵌套類,你將不得不在<Item>添加到它的聲明,因爲它的實例不會有Stack<Item>一個封閉的實例。即使在這種情況下,也不會出現隱藏的情況,也會導致同樣的錯誤。實際上,您也需要將類型變量添加到Node

+0

捕捉!我認爲你更好地描述它。 – OldCurmudgeon

0

嘗試這樣的:

import java.util.Iterator; 

public class Stack<Item> implements Iterable<Item> { 

    private Node first; 
    private int N; 

    private class Node { 
     private Node next; 
     private Node prev; 
     private Item item; 
    } 

    @Override 
    public Iterator<Item> iterator() { 
     return new ReverseIterator(); 
    } 

    private class ReverseIterator implements Iterator<Item> { 
     private Node x; 

     private ReverseIterator() { 
      if (first != null) { 
       x = first.prev; 
      } 
     } 

     public boolean hasNext() { 
      return x != null; 
     } 

     public Item next() { 
      Item i = x.item; 
      x = x.prev; 
      return i; 
     } 

     public void remove() { 
     } 
    } 

    public void push(final Item i) { 
     if (isEmpty()) { 
      first = new Node(); 
      first.item = i; 
      first.next = first; 
      first.prev = first; 
     } else { 
      Node x = new Node(); 
      x.item = i; 
      x.next = first; 
      x.prev = first.prev; 
      first.prev.next = x; 
      first.prev = x; 
     } 
     N++; 
    } 

    public Item pop() { 
     assert !isEmpty() : "Stack is empty"; 

     Item i = first.prev.item; 
     if (N == 1) { 
      first = null; 
     } else { 
      first.prev.prev.next = first; 
      first.prev = first.prev.prev; 
     } 

     N--; 
     return i; 
    } 

    public boolean isEmpty() { 
     return N == 0; 
    } 

    public int size() { 
     return N; 
    } 

    public static void main(final String[] args) { 

    } 
} 
1

你的問題是在這裏:

private class ReverseIterator<Item> implements Iterator<Item>{ 

在這裏你要定義一個內部類處理Item類型的對象,但該類型是不相同的類型Item類型的封閉Stack類。因此,當您做Item i = x.item;x.item類型Stack.Item(有點),而i類型Stack.ReverseIterator.Item

你有兩個選擇,一個是做的你做,使內部類使用相同的Item類型外,或者你可以讓內部類static並持有自己的內心Item型(雖然在這種情況下,我會建議爲內部類型使用不同的名稱,否則你會發現自己又會感到困惑)。

相關問題