为什么我需要在ListIterator中连续调用previous()两次才能进行“反向”迭代?

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

Why do I need to call previous() twice in ListIterator so I can go in 'reverse' iteration?

问题

我们知道ListIterator拥有next()previous()方法,使我们能够在两个方向上进行遍历。因此,我编写了一个小程序来尝试一下。

List<String> songs = new ArrayList<>();
songs.add("song1");
songs.add("song2");
songs.add("song3");
songs.add("song4");

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

System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());

System.out.println(iterator.previous());
System.out.println(iterator.previous());

我原本期望的输出是:

song1
song2
song3
song2
song1

但是我错误了。实际输出结果是:

song1
song2
song3
song3
song2

有人能告诉我为什么会发生这种情况吗?当我在song3这里时,游标不就在那个位置吗?所以当我执行previous()时,不应该给我它前面的歌曲吗?有什么简单的方法可以帮我理解这个概念吗?

英文:

We know what ListIterator has method next() and previous() that allow us to traverse in both directions. So I made a little program to try it out.

List&lt;String&gt; songs = new ArrayList&lt;&gt;();
   songs.add(&quot;song1&quot;);
   songs.add(&quot;song2&quot;);
   songs.add(&quot;song3&quot;);
   songs.add(&quot;song4&quot;);

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

    System.out.println(iterator.next());
    System.out.println(iterator.next());
    System.out.println(iterator.next());

    System.out.println(iterator.previous());
    System.out.println(iterator.previous());

What I was expecting is to get:

song1
song2
song3
song2
song1

But I was wrong. Actual result it this:

song1
song2
song3
song3
song2

Can someone tell me how does this happens? Isn't cursor when I am 'in' song3 literally there, so when I do previous() it gives me song before that one? How can I finally understand this concept the easy way?

答案1

得分: 1

因为文档中所说的 next() 会返回当前元素并将迭代器移动到下一个位置:

返回列表中的下一个元素并将光标位置向后移动。

所以当它打印出 song3 时,光标 移动到了 song3 的后面,然后如果你调用 previous(),你将会得到 光标 之前的元素,因此又是 song3

英文:

Because as the docs says next() gives you the current element AND moves the iterator to the next:

> Returns the next element in the list and advances the cursor position.

This when it prints song3 the cursor is moved just after song3, then if you call previous() you will get the element just before the cursor, hence song3 again.

答案2

得分: 1

看一下 ListIteratorjavadoc...

                     元素(0)      元素(1)      元素(2)      ... 元素(n-1)
游标位置:           ^             ^             ^             ^                  ^

在迭代开始时,游标位于第一个元素之前。

调用 next() (1) 检索游标位置之后的第一个元素并且 (2) 将游标移动到检索到的元素之后。

调用 previous() (1) 检索游标位置之前的第一个元素并且 (2) 将游标设置在检索到的元素之前。


让我们检查一下在你输出的第三行和第四行之间出现的问题是什么。

在输出的第二行之后,迭代器的状态:

                    "song1"   "song2"   "song3"   "song4"
游标位置:                               ^

现在你再次调用 next() 并输出 "song3"。迭代器的状态如下:

                    "song1"   "song2"   "song3"   "song4"
游标位置:                                             ^

此时你调用 previous() 并且 "song3" 被再次打印。操作后迭代器的状态如下:

                    "song1"   "song2"   "song3"   "song4"
游标位置:                               ^
英文:

Take a look at ListIterator's javadoc...

> Element(0) Element(1) Element(2) ... Element(n-1)
> cursor positions: ^ ^ ^ ^ ^

At the beginning of an iteration, cursor points before the first element.

A call to next() (1) retrieves the first element after the cursor position and (2) advances the cursor to point after the retrieved element.

A call to previous() (1) retrieves the first element before the cursor position and (2) sets the cursor to point before the retrieved element.


Lets examine what happens between your 3rd and 4th line of output that is problematic.

State of your iterator after the second line of output:

                    &quot;song1&quot;   &quot;song2&quot;   &quot;song3&quot;   &quot;song4&quot;
cursor position:                      ^

Now you call next() again and output &quot;song3&quot;. Your iterator state looks like this:

                    &quot;song1&quot;   &quot;song2&quot;   &quot;song3&quot;   &quot;song4&quot;
cursor position:                                ^

At this point you call previous() and &quot;song3&quot; gets printed again. The iterator state after the operation is as follows:

                    &quot;song1&quot;   &quot;song2&quot;   &quot;song3&quot;   &quot;song4&quot;
cursor position:                      ^

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

发表评论

匿名网友

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

确定