使用ListIterator在Java中的LinkedList上来回移动

我有一个LinkedList,我需要多次来回迭代。 我正在使用它来跟踪将动态创建的工作流中的一系列页面。 这并不像我期望的那样。 鉴于这个例子:

LinkedList navigationCases; navigationCases.add("page1"); navigationCases.add("page2"); navigationCases.add("page3"); navigationCases.add("page4"); ListIterator navigationItr = navigationCases.listIterator(); navigationItr.next(); // Returns page1 navigationItr.next(); // Returns page2 navigationItr.previous(); //Returns page2 again navigationItr.next(); //Returns page2 again 

我想也许我正在错误地构建我的列表,或者使用Iterator错误,但在阅读文档之后,这似乎是设计的:

ListIterator没有当前元素; 它的光标位置总是位于调用previous()返回的元素和调用next()返回的元素之间。

和:

(Next)返回列表中的下一个元素。 可以重复调用此方法以遍历列表,或者与之前的调用混合以来回传递。 (注意,对next和previous的交替调用将重复返回相同的元素。)

因此,在阅读本文之后,很明显为什么我的代码表现得像它那样。 我只是不明白为什么它应该这样工作。 甚至删除似乎是向后弯曲以适应这种实现:

请注意,remove()和set(Object)方法没有根据光标位置定义; 它们被定义为对next()或previous()调用返回的最后一个元素进行操作。

从概念上讲,LinkedList似乎很好地模拟了我的工作流案例,但我不能使用行为方式的Iterator。 我在这里遗漏了什么,或者我应该只写自己的class级来维护案例列表并浏览它们?

这应该做你的工作:

 public class Main { public static void main(String[] args) { final LinkedList list = new LinkedList (); list.add ("1"); list.add ("2"); list.add ("3"); list.add ("4"); final MyIterator it = new MyIterator (list.listIterator()); System.out.println(it.next()); System.out.println(it.next ()); System.out.println(it.next ()); System.out.println(it.previous ()); System.out.println(it.previous ()); System.out.println(it.next ()); } public static class MyIterator { private final ListIterator listIterator; private boolean nextWasCalled = false; private boolean previousWasCalled = false; public MyIterator(ListIterator listIterator) { this.listIterator = listIterator; } public T next() { nextWasCalled = true; if (previousWasCalled) { previousWasCalled = false; listIterator.next (); } return listIterator.next (); } public T previous() { if (nextWasCalled) { listIterator.previous(); nextWasCalled = false; } previousWasCalled = true; return listIterator.previous(); } } } 

还有一个小提琴 。

ListIterator旨在以这种方式运行。 请参阅ShyJ答案下的对话理由。

我发现这种行为超出了愚蠢的行为,而是编写了一个非常简单的替代方案。 这是带有ArrayLists扩展function的Kotlin代码:

 class ListIterator(var list: ArrayList) : Iterator { private var cursor: Int = 0 fun replace(newList: ArrayList) { list = newList cursor = 0 } override fun hasNext(): Boolean { return cursor + 1 < list.size } override fun next(): E { cursor++ return current() } fun hasPrevious(): Boolean { return 0 <= cursor - 1 } fun previous(): E { cursor-- return current() } fun current(): E { return list[cursor] } } fun  ArrayList.listFlippingIterator() = ListIterator(this) 

如果您希望包含删除function,我强烈建议编写API以显式指示迭代器是否应该向左或向右删除,例如通过将这些方法定义为removeNext()removePrevious()

做这样的事(伪代码) –

 class SkipIterator extends ListIterator { public E previous(){ E n = super.previous(); return super.previous(); } ... } 

然后:

 LinkedList navigationCases; navigationCases.add("page1"); navigationCases.add("page2"); navigationCases.add("page3"); navigationCases.add("page4"); SkipIterator navigationItr = (SkipIterator)navigationCases.listIterator(); navigationItr.next(); // Returns page1 navigationItr.next(); // Returns page2 navigationItr.previous(); // Returns page1 

干杯