【问题标题】:Why do I need to call previous() twice in ListIterator so I can go in 'reverse' iteration?为什么我需要在 ListIterator 中调用 previous() 两次才能进行“反向”迭代?
【发布时间】:2021-01-14 02:49:14
【问题描述】:

我们知道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 'in' 时,cursor 不就在那里,所以当我在previous() 时,它会给我before 那首歌?我怎样才能最终以简单的方式理解这个概念?

【问题讨论】:

  • ListIterator#previous() Javadoc 声明:“(注意交替调用 next 和 previous 将重复返回相同的元素。)”这与迭代器在调用 @ 时如何移动当前位置的事实有关987654330@ 和 previous().
  • 我明白了,但这没有意义。为什么会有人想把它弄得那样混乱?
  • next 实现返回当前项目,然后前进。这意味着在最后一次调用next 之后指针指向song4previous先前进后返回值,表示指针回到song3

标签: java iterator next


【解决方案1】:

看看ListIteratorjavadoc...

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

在迭代开始时,光标指向第一个元素之前。

调用next() (1) 检索光标位置之后的第一个元素,(2) 使光标前进到检索到的元素之后。

调用previous() (1) 检索光标位置之前的第一个元素,(2) 将光标设置为指向检索的元素之前。


让我们检查一下有问题的输出的第 3 行和第 4 行之间发生了什么。

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

                    "song1"   "song2"   "song3"   "song4"
cursor position:                      ^

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

                    "song1"   "song2"   "song3"   "song4"
cursor position:                                ^

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

                    "song1"   "song2"   "song3"   "song4"
cursor position:                      ^

【讨论】:

    【解决方案2】:

    因为正如文档所说,next() 为您提供了当前元素并将迭代器移动到下一个元素:

    返回列表中的下一个元素并前进光标位置。

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

    【讨论】:

    • 如果光标停留在当前迭代器上不是更有意义吗?为什么要推进它并用这个例子来压倒它?
    • @Stefan 并非 JDK 的所有方面都经过完美设计。这种实施已经存在了 22 年。他们不能改变语义,因为它会破坏人们的东西。在实践中,我认为我从来没有使用过双向迭代器。
    • @stefan 这是因为每个人在迭代时都会这样做,即t[i++],获取当前值并移动到下一个值。然后t[--i] 是相反的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多