为什么在迭代过程中无法看到来自迭代器的修改?

huangapple go评论137阅读模式
英文:

Why modifications from Iterator aren't visible during iteration?

问题

在学习了一段时间的Java后,我决定重新学习listIterator方法。所以我编写了以下简单的代码:

List<String> colors = new ArrayList<>();
colors.add("red");
colors.add("blue");
colors.add("green");

ListIterator<String> iterator = colors.listIterator();

while (iterator.hasNext()){
    String color = iterator.next();
    System.out.println(color);

    if (color.equals("blue")){
        iterator.add("yellow");
    }
}

我期望的是,iterator&#39;blue&#39;之后直接添加&#39;yellow&#39;。但是当我运行它时,我感到很惊讶。结果是:

red-blue-green

而不是我期望的:

red-blue-yellow-green

迭代期间iteratoradd()方法没有更新集合时,这有什么意义呢?是的,如果我调用System.out.println(colors),它会显示所有4种颜色。但为什么不简单地添加&#39;yellow&#39;,这样Iterator就可以'看到'它呢?

英文:

After some time learning Java, I decided to revise listIterator methods. So I made following simple code:

List&lt;String&gt; colors = new ArrayList&lt;&gt;();
colors.add(&quot;red&quot;);
colors.add(&quot;blue&quot;);
colors.add(&quot;green&quot;);

ListIterator&lt;String&gt; iterator = colors.listIterator();

while (iterator.hasNext()){
    String color = iterator.next();
    System.out.println(color);

    if (color.equals(&quot;blue&quot;)){
        iterator.add(&quot;yellow&quot;);
    }
}

What I was expecting was that iterator adds &#39;yellow&#39; right after &#39;blue&#39;. But when I run it, I got surprised. Result is :

red-blue-green

And not as I expected:

red-blue-yellow-green

What is the point of iterator's add() method when it is not updating collecting during iteration? And yes, if I were to call System.out.println(colors), it would show me all 4 colors. But why not simply add &#39;yellow&#39; so Iterator can 'see' it?

答案1

得分: 4

首先,这样做是因为它是如此指定的:

关于 ListIterator.add 的 JavaDocs
> 新元素被插入到隐式游标之前:随后对 next 的调用不受影响,并且随后对 previous 的调用将返回新元素。

我认为这个决定背后的理由可能是这样的:
如果你刚刚添加了一个元素,通常你不会立即在下一次对 next() 的调用中对其进行处理。相反,更常见的情况是你希望基于开始迭代之前集合中包含的元素向集合中添加元素。你已经知道刚刚添加的元素,因此可以直接进行任何它所需的处理。

英文:

First of all, it is like that because that is how it is specified:

JavaDocs for ListIterator.add:
> The new element is inserted before the implicit cursor: a subsequent call to next would be unaffected, and a subsequent call to previous would return the new element.

I suppose the rationale behind this decision is something like this:
If you just added an element, you are usually not interested to immediately processing it on the next call to next(). Instead, most frequently you just want to add elements to the collection based on the elements that it contained before starting the iteration. You already know the element you just added, so you can just do any processing it needs directly.

答案2

得分: 2

根据ListIterator的add方法的Java文档,调用nextIndexpreviousIndex的返回值将增加1,因此当你添加元素时,游标会移动到该项,并在调用next()时,游标会返回添加的元素之后的元素。为了看到这一点,您需要调用.previous(),然后再调用next()

英文:

As per the java docs for add method of ListIterator, the add will increase by 1 the value to returned by a call to nextIndex or previousIndex, so when you added, cursor moved to this item and on next(), cursor returned the element after your added element. In order to see, you will have to call .previous() and then next().

huangapple
  • 本文由 发表于 2020年9月28日 12:13:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64095866.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定