如何在列表迭代器(反向)迭代期间正确添加对象?



我的教授要求我使用listiterator在ArrayedList<Employee>中间添加一个对象。

我首先尝试通过以下方式进行操作:

ListIterator < Employee > li = emps.listIterator(emps.size());
System.out.println("nUsing ListIterator:n");
i = 1;
while (li.hasPrevious()) {
if (li.nextIndex() == 5) {
li.add(emp_M);
}
System.out.println("  Employee " + (i++) + " " + li.previous());
}

但这会产生看似无限次的迭代,其中li.nextIndex()停留在 5 上。 我已经用调试器验证了这一点,这只有在评估li.add(emp_M)后才会发生。

我找到了一个解决方案,我在li.add(emp_M)后立即添加了一个break,并继续以相同的方式单独解析列表,但根本没有添加到列表中emp_M

//parse in two loops to add the middle employee, without the break the list seemingly spirals into infinity!
System.out.println("nUsing ListIterator:n");
i = 1;
while (li.hasPrevious()) {
if (li.nextIndex() == 5) {
li.add(emp_M);
System.out.println("ADDED IN MIDDLE");
break;
}
System.out.println("  Employee " + (i++) + " " + li.previous());
}
while (li.hasPrevious()) {
System.out.println("  Employee " + (i++) + " " + li.previous());
}

这让我不禁要问,我所做的是懒惰和幼稚的方法吗?我还能如何添加到带有listIterator的列表中?

代码中的问题是您将无限期地添加元素emp_M

如果我们进行一次迭代,在其中添加一个元素:

假设li.nextIndex() == 5,那么你将向迭代器添加一个新元素,并且根据 add 的文档,你还将增加一个索引(因此你将迭代器向右移动)。然后你的循环继续,你用li.previous()将迭代器移到左边,这恰好是在你添加元素之前放置的(并验证要添加的 if 条件)。

现在,您开始 while 循环的新版本迭代,再次验证条件,添加新元素等...您将停留在通过无限期添加新元素来验证条件的元素上。

为了使代码更容易,请尝试在文档方向(即e1 -> e2 -> e3 -> e4)上运行迭代器

ListIterator < Employee > li = emps.listIterator();
i = 1;
while (li.hasNext()) {
if (li.nextIndex() == 5) {
li.add(emp_M);
}
System.out.println("  Employee " + (i++) + " " + li.next());
}

我在调试器中深入研究后找到了它。

在添加li.nextIndex() == 5li.previousIndex() == 4之前的时刻 添加对象后,上述更改li.nextIndex() == 6li.previousIndex() == 5这是因为listIterator的.add().next()之前插入对象。

继续解决这个问题会建立一个来回循环,其中li.previous()li.previousIndex()li.nextIndex()都减少 1,而调用li.add(emp_M)会将上述两个值都减少 1。

要修复它,我们需要在添加后跳过添加的元素:

System.out.println("nUsing ListIterator:n"); 
i = 1;
while (li.hasPrevious())
{
if(li.nextIndex() == 5)
{
li.add(emp_M);
li.previous();
System.out.println("ADDED IN MIDDLE");
//              break;
}
System.out.println("  Employee " + (i++) + " " + li.previous());
}

这有效地否定了上述问题。

有时,只需提出一个问题,您就可以自己找到答案!

如果有人能比我理解的更好地向我解释,我将延迟接受我自己的答案。

最新更新