ListIterator previous() and next() result

621 Views Asked by At

result is

A B C D

D C C2 B2 B A

Why isn't result

A B B2 C D

D C C2 B2 B A in first while ?

I did li.add("B2") if word.equals"B". Is it just difference between next() and previous() ? I want to know answer please.

public static void main(String[] args) {

    List<String> list = Arrays.asList("A", "B", "C", "D");
    list = new ArrayList<>(list);
    ListIterator<String> li = list.listIterator();
    String word;

    while (li.hasNext()) {
        word = li.next();
        System.out.print(word + '\t');
        if (word.equals("B"))
           li.add("B2");
    }

    System.out.println();

    while (li.hasPrevious()) {
        word = li.previous();
        System.out.print(word + '\t');
        if (word.equals("C"))
            li.add("C2");
    }
}
5

There are 5 best solutions below

0
Mateusz Jaszewski On BEST ANSWER

I think that answer for your question is here - https://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html#add(E).

The element is inserted immediately before the element that would be returned by next(), if any, and after the element that would be returned by previous(), if any.

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.

At first loop when word equals "B" the implicit cursor is between "B" and "C", according to the documentation the new element will be added before it.

A    B       C     D
       ^   ^ 
      B2  cursor
 
0
Dakshinamurthy Karra On

The JavaDoc for ListIterator#add specifies the behaviour:

 * Inserts the specified element into the list (optional operation).
 * The element is inserted immediately before the element that
 * would be returned by {@link #next}, if any, and after the element
 * that would be returned by {@link #previous}, if any.  (If the
 * list contains no elements, the new element becomes the sole element
 * on the list.)  The new element is inserted before the implicit
 * cursor: a subsequent call to {@code next} would be unaffected, and a
 * subsequent call to {@code previous} would return the new element.

Where is the confusion?

1
OldCurmudgeon On

See ListIterator.add(E):

... The element is inserted immediately before the element that would be returned by next() ...

So in your first iteration, the addition of B2 will not become the next one in the list.

0
Anton Belev On

https://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html

The reason is that when you are adding element to the iterator this is not changing the next() element but the previous() only. Thus when you add "B2" and "C2" it is only going to be picked up by previous() calls. And that's why the first iteration is not picking up B2 and C2 and the second backwards iteration picks both of them.

1
Joakim Danielson On

You can see the list change by changing your print to use nextIndex like this

System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');


while (li.hasNext()) {
    System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');
    word = li.next();
    if (word.equals("B")) {
         li.add("B2");
    }
  }

System.out.println();

while (li.hasPrevious()) {
    word = li.previous();
    System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');
    if (word.equals("C"))
        li.add("C2");
    }
}

This outputs

A[0]    B[1]    C[3]    D[4]     
D[4]    C[3]    C2[3]   B2[2]   B[1]    A[0]