任何人都可以解释我收到此错误的原因吗?
这是我使用双向链表实现的堆栈类:
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;
,期望的Item,找到Item有错误。解决方案是将ReverseIterator<Item>
替换为ReverseIterator
。有人可以解释为什么我通过添加<Item>
得到了错误吗?
由于
答案 0 :(得分:4)
仅仅因为您对类型变量(Item
)使用相同的名称并不意味着它代表相同的泛型类型。
如果在通用类N<T>
中声明嵌套类C<T>
,T
中的C<T>
实际上会隐藏在N<T>
的正文中。它与声明名为x
的类级别字段并在该类中声明方法参数(也称为x
)的原理完全相同。你内心的声明范围隐藏了任何东西。
如果ReverseIterator
是 static 嵌套类,则必须将<Item>
添加到其声明中,因为它的实例不会包含Stack<Item>
{1}}。并且会导致相同的错误,即使在这种情况下也不会隐藏。实际上,您还需要将类型变量添加到Node
。
答案 1 :(得分: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
类型(虽然在这种情况下我会建议为内部类型使用不同的名称,否则您会发现自己再次感到困惑。)
答案 2 :(得分: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) {
}
}