使用ListIterator在Java中的LinkedList上来回移动
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ListIterator在Java中的LinkedList上来回移动相关的知识,希望对你有一定的参考价值。
我有一个LinkedList,我需要多次来回迭代。我正在使用它来跟踪将动态创建的工作流中的一系列页面。这并不像我期望的那样。鉴于这个例子:
LinkedList<String> 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似乎很好地模拟了我的工作流程案例,但我不能使用行为方式的迭代器。我在这里遗漏了什么,或者我应该写自己的班级来维护案例列表并浏览它们?
这应该做你的工作:
public class Main {
public static void main(String[] args) {
final LinkedList<String> list = new LinkedList<String> ();
list.add ("1"); list.add ("2"); list.add ("3"); list.add ("4");
final MyIterator<String> 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<T> {
private final ListIterator<T> listIterator;
private boolean nextWasCalled = false;
private boolean previousWasCalled = false;
public MyIterator(ListIterator<T> 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();
}
}
}
还有一个fiddle。
ListIterator旨在以这种方式运行。请参阅ShyJ答案下的对话理由。
我发现这种行为超出了愚蠢的行为,而是编写了一个非常简单的替代方案。这是带有ArrayLists扩展功能的Kotlin代码:
class ListIterator<E>(var list: ArrayList<E>) : Iterator<E> {
private var cursor: Int = 0
fun replace(newList: ArrayList<E>) {
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 <E> ArrayList<E>.listFlippingIterator() = ListIterator(this)
如果您希望包含删除功能,我强烈建议编写API以明确指示迭代器是否应该向左或向右移除,例如通过将这些方法定义为removeNext()
和removePrevious()
。
做这样的事(伪代码) -
class SkipIterator extends ListIterator {
public E previous(){
E n = super.previous();
return super.previous();
}
...
}
然后:
LinkedList<String> 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
干杯
以上是关于使用ListIterator在Java中的LinkedList上来回移动的主要内容,如果未能解决你的问题,请参考以下文章
java:集合输出之Iterator和ListIterator
Java:list.listIterator() 返回的对象属于哪个类?
Java ListIterator 中的哪个元素被认为是先前的?