有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

尝试在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;,expected Item,found Item中有一个错误。解决办法是用ReverseIterator替换ReverseIterator<Item>。有人能解释一下为什么我在上面加了<Item>这个错误吗

谢谢


共 (2) 个答案

  1. # 1 楼答案

    试着这样做:

    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) {
    
        }
    }
    
  2. # 2 楼答案

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

    如果声明一个嵌套类N<T>,在泛型类C<T>内,来自C<T>T有效地隐藏在N<T>的主体中。这与声明一个名为x的类级字段以及在该类中声明一个名为x的方法参数的原理完全相同。最内层的声明范围会对外部隐藏任何内容

    如果ReverseIterator是一个静态嵌套类,则必须将<Item>添加到其声明中,因为它的实例不会包含Stack<Item>的封闭实例。同样的错误也会出现,即使在这种情况下,不会有隐藏发生。实际上,还需要将类型变量添加到Node