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;
}

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

3 回答 3

4

仅仅因为您为类型变量 ( Item) 使用了相同的名称,并不意味着它代表相同的泛型类型。

如果N<T>在泛型类中声明嵌套类C<T>,则TfromC<T>有效地隐藏在N<T>. x这与在该类中声明一个名为的类级别字段和声明一个方法参数的原理完全相同,也称为x. 你最里面的声明范围从外面隐藏了任何东西。

如果ReverseIterator静态嵌套类,则必须在<Item>其声明中添加 ,因为它的实例不会有Stack<Item>. 即使在这种情况下不会有任何隐藏,也会导致同样的错误。实际上,您还需要添加类型变量Node

于 2012-06-09T00:26:15.280 回答
1

你的问题在这里:

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

在这里,您定义了一个处理对象类型的内部类,Item但这种类型Item与封闭Stack类的类型不同。结果,当您执行Item i = x.item; x.itemis of type Stack.Item(sort of) while iis of type时Stack.ReverseIterator.Item

您有两种选择,一种是按照您的做法做,让内部类使用与Item外部相同的类型,或者您可以让内部类使用static自己的内部Item类型(尽管在这种情况下,我建议使用不同的名称对于内部类型,否则您会再次感到困惑)。

于 2012-06-09T00:29:41.703 回答
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) {

    }
}
于 2012-06-09T00:28:55.950 回答