Is iterator's rule of Iterator and Listiterator different from each other?(Java)

Viewed 42

I'm practicing Java code - iterator and listIterator
and having a hard time understanding the result of the code below.

Code:

import java.util.*;

public class ListIteratorCollection {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A","B","C","D");
        list = new ArrayList<>(list);

        ListIterator<String> litr = list.listIterator();
        String str;

        while(litr.hasNext()){
            str = litr.next();
            System.out.print(str + '\t');
            if(str.equals("A"))
                litr.add("A-add");
        }
        System.out.println();

        while(litr.hasPrevious()){
            str = litr.previous();
            System.out.print(str + '\t');
            if(str.equals("C"))
                litr.add("C-add");
        }
        System.out.println();

        for(Iterator<String> itr = list.iterator(); itr.hasNext();)
            System.out.print(itr.next() + '\t');
        System.out.println();
    }
}

Result:

A B C D
D C C-add B A-add A
A A-add B C-add C D

I wonder why A-add is not printed (in the first while loop), but C-add is printed (in the second while loop). Both of them are just newly added to the existing list, and the while loop structure is alike (I think?).

Can anyone explain this?

1 Answers

This is explained by the documentation of 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.

So in your example (^ indicating the cursor)

  1. First iteration (forward):
    A B C D
     ^ →
    
    // litr.add("A-add");
    A A-add B C D
           ^ →
    
  2. Second iteration (backward)
    A A-add B C D
           ← ^
    
    // litr.add("C-add");
    A A-add B C-add C D
                 ← ^
    
  3. Third iteration (forward)
     A A-add B C-add C D
    ^ →
    
Related