ListIterator 的 Previous() 方法 class

Previous() method of the ListIterator class

我的输出打印 null 以及不应该打印的元素。例如,

        MyList<String> l = new MyList<String>();
        l.add("A");
        l.add("B");
        l.add("C");
        l.add("D");
        l.add("E");
        ListIterator<String> iter = l.listIterator(l.size());
        while(iter.hasPrevious()){
            Object element = iter.previous();
            System.out.print(element + " ");
        }

结果是:

null E D C B A 

previous() 方法有什么问题,我该如何解决它才能不打印 null

protected Node<T> beginMarker;  // Dummy node marking the front of the list
protected Node<T> endMarker;    // Dummy node marking the back of the list
....................
public class AListIterator implements ListIterator<T>{
        protected Node<T> current;                
        protected Node<T> lastVisited = null;     
        protected int expectedModCount = modCount;
public boolean hasPrevious( ){
            if( expectedModCount != modCount )
                throw new ConcurrentModificationException( );

            return current != beginMarker;
        }

public T previous( ){
            if( expectedModCount != modCount )
                throw new ConcurrentModificationException( );
            if(!hasPrevious( ))
                throw new RuntimeException("Already at beginning of list"); 

            T prevItem = current.data;
            current = current.prev;
            return prevItem;
        } 

两端不需要虚拟标记。这是因为对于长度为 nListListIterator 只有 n + 1 个可能的光标位置(在每个 n 元素之前和最后一个元素之后element)。因此你只需要一个虚拟节点。

我会去掉 endMarker 并将其替换为对最后一个节点的引用。然后,当您调用 l.listIterator(l.size()) 时,您将获得一个迭代器,其中 current 最初是最后一个节点,因此您不会在迭代开始时获得 null

你的问题的原因是current的初始化不正确。当迭代开始时(在构建之后),current 应该指向最后一个元素(当指定的位置是列表的大小时),或者 null 如果没有前面的元素(位置 0,或空列表)。

您不需要开始标记。在最后一次调用 previous 后,Current 将变为 null,因此您可以改用简单的 null 检查。

您也不需要结束标记(无论如何在发布的代码中都没有使用它)。

顺便说一句,在超出末尾的情况下抛出的常见异常是 NoSuchElementException。