Iterator接口

Hen*_*old 8 java iterator iterable linked-list

我有一个大学的分配,要求我实现一个实现Iterator接口的内部类.迭代器适用于单链表超类.

目前我的内部类看起来像这样:

private class ListIterator implements Iterator<V>{

    Node temp;
    boolean nextCalled = false;

    ListIterator(Node fo){
        this.temp = fo;
    }

    @Override
    public boolean hasNext() {
        if(temp != null){
            return true;
        }
        return false;
    }

    @Override
    public V next() {
        nextCalled = true;
        return temp.getReprValue();
    }

    @Override
    public void remove() {
        if(nextCalled && hasNext()){
            nextCalled = false;
            removeElement(temp.getReprKey());
            temp = temp.getNext();
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,即使列表实际为空,hasNext()方法也返回true.其他一切似乎都有效.我可能忽略了某处的逻辑缺陷,但我自己找不到它.

Fra*_*ank 5

您需要跟踪列表中的位置,实现a cursor,或者如果链接列表中的节点知道它们next,请询问它们是否具有下一个元素.当光标较大时,长度/你的节点没有next你在hasNext()中返回false.

在你的hasNext()方法中完成所有这些.请记住,如果hasNext()将false设置为next()则抛出异常是可以的 - 所以你需要确保它是唯一一次抛出异常.

由于我不知道列表的基础数据结构,我不能告诉你哪一个会更好.


Cae*_*alf 5

更改了您的实现以反映Iterator合同需要的内容.您需要记住,您需要能够遍历集合的所有元素,即,next()应该从第一个元素开始,并且在每次调用之后,它必须将当前的下一个元素更改为列表中的下一个元素,否则抛出异常没有.

阅读Iterator接口文档以了解您需要实现它并从那里开始的方式是很好的.

private class ListIterator implements Iterator<V> {
    private Node next;
    private boolean alreadyDeleted = false;

    ListIterator(Node node){
        this.next = node;
    }

    @Override
    public boolean hasNext() {
        // because next is the current element. We need to iterate over all the elements
        // from the collection.
        return next != null;
    }

    @Override
    public V next() {
        if (next == null) {
           throw new NoSuchElementException();
        }

        Node current = next;

        this.next = current.getNext();
        this.alreadyDeleted = false; // it's better to try to elimate this state variable. You can try to do in another way, if yours removeElement returns something

        return current;
    }

    @Override
    public void remove() {
        if (alreadyDeleted || next == null) {
           throw new IllegalStateException();
        }
        removeElement(next.getReprKey());
        this.alreadyRemoved = true;
    }

}
Run Code Online (Sandbox Code Playgroud)