【问题标题】:Generic Iterator implementation in javaJava中的通用迭代器实现
【发布时间】:2011-12-15 13:26:20
【问题描述】:

我有以下设计: 我有一个抽象类Instance, 我有一个类Library 扩展Instance 和 我有一个类 File 也扩展了 Instance

我已经创建了自己的链表实现,它的定义如下:

public class List<T extends Instance> implements Iterable {
    //some other code here

     public Iterator iterator(){
         return new ListIterator(this);

}

现在我已经创建了一个类

public class ListIterator<T extends Instance> implements Iterator<T> {
    private List thisList;
    private Node current;

    public ListIterator(List l){
        thisList=l;
        current=thisList.head.next;
    }
    @Override
    public boolean hasNext() {
        if(current==null)
            return false;
        return false;
    }

    @Override
    public T next() {
        Node temp=current;
        current=current.next;
        return temp.data;
    }
}

Node 在哪里

public class Node<T extends Instance> {
    public Node<T> next;
    public Node<T> prev;
    public T data;

    public Node(T data,Node prev, Node next){
        this.data=data;
        this.prev=prev;
        this.next=next;
    }   
}

所以我的问题如下:return temp.data这一行出现错误:

类型不匹配 - 无法从 Instance 转换为 T。

这段代码有什么问题?

【问题讨论】:

  • 如果您发布 Node 类的代码,将更容易弄清楚发生了什么。还有……这不是……作业,是吗?
  • 因为 (1) 如果不是为了作业(或至少是私人学习),那么自己实施 List 可能是个坏主意,以及 (2) 如果它是对于家庭作业,那么我们应该帮助你从错误中吸取教训,而不是给你答案。
  • 顺便说一句,如果您使用的是 Eclipse、IntelliJ 等 IDE,请打开选项以在您使用原始类型而不是泛型时发出警告。它会给你一个额外的指针来解决这类问题。 (尽管如果你深入研究泛型,你也会遇到一些你无法摆脱的警告。泛型是一种痛苦。)
  • 还有一个提示 - 然后我就不再打扰你了 - 阅读 Josh Bloch 的 Effective Java,其中包含一个解释(比我更有说服力)为什么你不应该编写自己的列表的项目 -当然,除了作为学习练习。顺便说一句,Josh Bloch 是编写 Java 集合 API 的工程师之一。

标签: java generics iterator


【解决方案1】:

我会说Node.data 是对Instance 对象的引用?如果是这种情况,编译器不能自动将Instance 更改为T,因为即使T 是Instance 对象(T extends Instance),任何给定的Instance 也可能不是T.

Java 泛型教程解释它:http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html

另外,在您的List&lt;T&gt; 类中,您应该使用Iterator&lt;T&gt; 和ListIterator&lt;T&gt; 将Iterator 和ListIterator 指定为泛型,否则编译器将无法正确处理泛型。您的Node 参考也需要是通用的:Node&lt;T&gt;

因此你应该使用

private Node<T> current;

和

public T next() {
    Node<T> temp=current;
    current=current.next;
    return temp.data;
}

当您为泛型类使用原始类型时,编译器通常会警告您。

【讨论】:

  • Node.data 是 T 类型,T 扩展实例
  • 我已经更新了我的答案:您需要将 Node 指定为 Node 否则它将被视为无类型(因此属于 Instance 类型,而不是 T)
  • 我认为这就是 OP 想要的答案。我只是故意字面意思。
【解决方案2】:

没有人注意到这个错误:

public boolean hasNext() {
    if(current==null)
        return false;
    return false;
}

这是一个不变量。除非我遗漏了什么,否则迭代器将很快返回 0 个元素!

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2018-04-05
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    相关资源
    最近更新 更多