ListIterator类的Previous()方法

时间:2015-10-07 04:19:02

标签: java doubly-linked-list

我的输出会在不应该的时候打印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 

上一个()方法出了什么问题?如何修复它以便它不会打印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;
        } 

2 个答案:

答案 0 :(得分:1)

你两端都不需要虚拟标记。这是因为ListIteratorList n只有n + 1个可能的光标位置(在每个n元素之前,并且在最后一个之后) element)。因此,您只需要一个虚拟节点。

我摆脱endMarker并将其替换为对最后一个节点的引用。然后,当你调用l.listIterator(l.size())时,你会得到一个迭代器,其中current最初是最后一个节点,所以你不会在迭代开始时得到null

答案 1 :(得分:1)

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

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

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

顺便说一句,在迭代结束时抛出的常见异常是NoSuchElementException。