2012-06-09 3 views
0

Может кто-нибудь объяснить, почему я получаю эту ошибку?Ошибка при использовании дженериков при попытке реализовать Iterable в Java

Вот стек класс I реализован с использованием дважды связанный списка:

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<Item> на ReverseIterator. Может кто-нибудь объяснить, почему я получил ошибку, которую я сделал, добавив <Item>?

Благодаря

ответ

4

Просто потому, что вы использовали такое же имя для переменной типа (Item) не означает, что она представляет собой один и тот же общий тип.

Если вы объявляете вложенный класс N<T>, внутри родового класса C<T>, то T из C<T> эффективно скрыты от тела N<T>. Это точно такой же принцип, как объявление поля уровня класса, называемого x, и объявление параметра метода в этом классе, также называемого x. Ваша самая внутренняя область объявления скрывает что-либо снаружи.

Если ReverseIterator были вложенным классом статический, вы обязаны добавить <Item> в своей декларации, поскольку случаи него не будет иметь закрывающий экземпляр Stack<Item>. И такая же ошибка будет, хотя в этом случае не будет скрываться. Фактически, вам нужно будет добавить переменную типа в Node.

+0

Snap! И я думаю, ты лучше описал это. – 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 типа (хотя и в этом случае Я бы рекомендовал использовать другое имя для внутреннего типа, иначе вы снова будете смущены).

 Смежные вопросы

  • Нет связанных вопросов^_^