Search code examples
javacollectionsiteratorlistiterator

ListIterator repeating elements on alternate calls of next() and previous()


I wrote the below programm to iterate in the list, but on alternate traversal next() and previous() it is repeating the element. I know the fix by putting an indicator and making use of it for extra next and extra previous prior to my printing logic. But i want to know why is the behaviour is like this and what is the algorithm behind the working of iterator.

I checked the javaDoc already and there its written like,

next
Returns the next element in the list. This method may be called repeatedly to iterate through the list, or intermixed with calls to previous to go back and forth. (Note that alternating calls to next and previous will return the same element repeatedly.)

but the question is why? and what is the logic or purpose behind doing so?

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;
        }

    }

}

}

as per @vincrichaud answer and java doc statement cursor points in between the element not on the element, Why is that so? is there any specific reason for it.

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

Solution

  • As explained in the doc

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

    Previous Returns the previous element in the list and moves the cursor position backwards.

    What is not obvious is that the cursor position is always between element and not on element. It's also described in the doc.

    A ListIterator has no current element; its cursor position always lies between the element

    So knowing this, that's pretty obvious that when you call alternatively next() and previous() you will obtain the same element.

    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