ListIterator 在 next() 和 previous() 的交替调用中重复元素

Posted

技术标签:

【中文标题】ListIterator 在 next() 和 previous() 的交替调用中重复元素【英文标题】:ListIterator repeating elements on alternate calls of next() and previous() 【发布时间】:2018-03-23 09:25:46 【问题描述】:

我编写了以下程序来迭代列表,但在交替遍历 next() and previous() 时它正在重复元素。我通过在我的打印逻辑之前放置一个指示器并将其用于extra nextextra previous 来知道修复。但我想知道为什么会出现这样的行为以及迭代器工作背后的算法是什么。

我已经检查了 javaDoc,它的写法是这样的,

下一个 返回列表中的下一个元素。这个方法可以调用 反复遍历列表,或与调用混合 以前来回走。 (注意交替调用 next 而 previous 将重复返回相同的元素。)

但问题是为什么?这样做的逻辑或目的是什么?

public class IterateLinkedListUsingListIterator 

public static void main(String[] args) throws NumberFormatException,
        IOException 
    LinkedList lList = new LinkedList();

    lList.add("1");
    lList.add("2");
    lList.add("3");
    lList.add("4");
    lList.add("5");

    ListIterator itr = lList.listIterator();
    boolean ch = true;

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    while (ch) 
        System.out.println("Enter choice");
        int chi = Integer.parseInt(br.readLine());
        switch (chi) 
        case 1:
            if (itr.hasNext()) 
                System.out.println(itr.next());
            
            break;
        case 2:

            if (itr.hasPrevious()) 
                System.out.println(itr.previous());
            
            break;

        default:
            ch = false;
        

    




根据@vincrichaud 的回答和java doc 语句,光标指向元素之间而不是元素上,为什么会这样?有什么具体的原因吗。

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

【问题讨论】:

这是一个合理的问题。 ListIterators 有点奇怪,几乎没有使用过。理解它们的方法是将当前位置视为两个元素之间。当您调用 next() 时,您会越过右侧的元素(并返回它)。当您可以使用 previous() 时,您会越过左侧的元素(并返回它)。这可能看起来很奇怪,但事实就是如此。 这就像在同一个对象上反复左右跳跃。你跳过的对象永远不会改变。如果你想让被跳过的物体改变你必须向同一个方向跳跃两次 【参考方案1】:

如doc中所述

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

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

不明显的是光标位置总是在元素之间而不是元素上。文档中也有描述。

ListIterator 没有当前元素;它的光标位置总是在元素之间

知道这一点,很明显,当您交替调用 next()previous() 时,您将获得相同的元素。

LinkedList lList = new LinkedList();
lList.add("1");
lList.add("2");
lList.add("3");
lList.add("4");
lList.add("5");
//lList look like [1,2,3,4,5]
ListIterator itr = lList.listIterator(); //create iterator at position before element 0

itr.next() // return the next element => so return "1"
           // And advance the cursor position => position between element 0 and element 1

itr.previous(); // return the previous element => so return "1"
           // And step back the cursor position => position before element 0

【讨论】:

好的,根据您的回答,现在行为很好,但为什么光标放在元素之间而不是元素上。 我不知道。询问甲骨文。我认为这是因为这样做更“合乎逻辑”。光标指示您已经经历了哪些元素,哪些没有。否则,指向的元素既不会被看到也不会被看到。此外,如果指向元素功能(例如 nextprevious 应该是 getElementAndMoveForwardgetElementAndMoveBackward 我认为用户不太友好

以上是关于ListIterator 在 next() 和 previous() 的交替调用中重复元素的主要内容,如果未能解决你的问题,请参考以下文章

java.util.ListIterator

ListIterator和Iterator

java:集合输出之Iterator和ListIterator

java 15 -7 ListIterator 的特有方法

Iterator与ListIterator的区别

Java 集合系列—— ListIterator 源码分析