The following code with listiterator is running infinitely

43 views Asked by At

I am trying to iterate through a list using listiterator using previous method. In the loop If I try to add elements using listiterator.add method the loop is getting iterated infinitely

I tried to debug the code but I couldn't find the exact reason

public static methodOne() {
    List l = new ArrayList();
    for(int i = 0; i < 5; i++) {
     l.add(i);
    }
    ListIterator li = l.listIterator();
    while(li.hasNext()) {
     li.next();
    }
    while(li.hasPrevious()) {
     Integer i = (Integer)li.previous();
     li.add(56);
    }
    System.out.println(l);
}

I expect the output to be 56,0,1,56,2,56,3,56,4,56,5

2

There are 2 answers

0
Kartik On

Your last loop runs infinitely because you keep adding an element and checking if it has previous. Of course it has previous, the one that you just added.

You can achieve what you want by:-

List<Integer> list = IntStream.range(0, 5)
        .flatMap(i -> IntStream.of(56, i))
        .boxed()
        .collect(Collectors.toList());
System.out.println(list);

Output

[56, 0, 56, 1, 56, 2, 56, 3, 56, 4]
0
Andreas On

If you read the documentation, i.e. the javadoc of ListIterator.add() you will see:

Inserts the specified element into the list (optional operation). 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. (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 next would be unaffected, and a subsequent call to previous would return the new element. (This call increases by one the value that would be returned by a call to nextIndex or previousIndex.)

So, alternating calls to previous() and add() will keep insert values at the same position in the list, and hence will never end (until memory runs out).

To show what happens, try this code:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>(Arrays.asList(10, 20, 30, 40));
    ListIterator<Integer> listIter = list.listIterator(list.size());
    print(list, listIter); // Iterator is at end (after 40)

    System.out.println("previous(): " + listIter.previous()); // prints: 40
    print(list, listIter); // Iterator is between 30 and 40

    for (int i = 39; i >= 31; i--) {
        listIter.add(i);   System.out.printf("add(i)%n", i);
        print(list, listIter);

        System.out.println("previous(): " + listIter.previous());
        print(list, listIter);
    }
}
static void print(List<Integer> list, ListIterator<Integer> listIter) {
    for (Integer i : list)
        System.out.printf("%5d", i);
    System.out.printf("%n%" + (listIter.nextIndex() * 5 + 2) + "s%n", "^");
}

Output

   10   20   30   40
                     ^
previous(): 40
   10   20   30   40
                ^
add(i)
   10   20   30   39   40
                     ^
previous(): 39
   10   20   30   39   40
                ^
add(i)
   10   20   30   38   39   40
                     ^
previous(): 38
   10   20   30   38   39   40
                ^
add(i)
   10   20   30   37   38   39   40
                     ^
previous(): 37
   10   20   30   37   38   39   40
                ^
add(i)
   10   20   30   36   37   38   39   40
                     ^
previous(): 36
   10   20   30   36   37   38   39   40
                ^
add(i)
   10   20   30   35   36   37   38   39   40
                     ^
previous(): 35
   10   20   30   35   36   37   38   39   40
                ^
add(i)
   10   20   30   34   35   36   37   38   39   40
                     ^
previous(): 34
   10   20   30   34   35   36   37   38   39   40
                ^
add(i)
   10   20   30   33   34   35   36   37   38   39   40
                     ^
previous(): 33
   10   20   30   33   34   35   36   37   38   39   40
                ^
add(i)
   10   20   30   32   33   34   35   36   37   38   39   40
                     ^
previous(): 32
   10   20   30   32   33   34   35   36   37   38   39   40
                ^
add(i)
   10   20   30   31   32   33   34   35   36   37   38   39   40
                     ^
previous(): 31
   10   20   30   31   32   33   34   35   36   37   38   39   40
                ^