我的输出会在不应该的时候打印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;
}
答案 0 :(得分:1)
你两端都不需要虚拟标记。这是因为ListIterator
长List
n
只有n + 1
个可能的光标位置(在每个n
元素之前,并且在最后一个之后) element
)。因此,您只需要一个虚拟节点。
我摆脱endMarker
并将其替换为对最后一个节点的引用。然后,当你调用l.listIterator(l.size())
时,你会得到一个迭代器,其中current
最初是最后一个节点,所以你不会在迭代开始时得到null
。
答案 1 :(得分:1)
问题的原因是当前的初始化不正确。当迭代开始时(构造后),当前应该指向最后一个元素(当指定位置是列表的大小时),如果没有前面的元素(位置0或空列表),则为null。
您不需要开始标记。在最后一次调用previous
后,当前将变为空,因此您可以使用简单的空检查。
您也不需要结束标记(无论如何都未在发布的代码中使用)。
顺便说一句,在迭代结束时抛出的常见异常是NoSuchElementException。