Следующий код с listiterator работает бесконечно - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь перебрать список, используя listiterator, используя предыдущий метод.В цикле Если я пытаюсь добавить элементы с помощью метода listiterator.add, цикл повторяется бесконечно

Я попытался отладить код, но не смог найти точную причину

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

Я ожидаю, что выход будет 56,0,1,56,2,56,3,56,4,56,5

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Если вы прочитаете документацию , то есть Javadoc ListIterator.add(), вы увидите:

Вставляет указанный элемент в список (необязательная операция). Элемент вставляется непосредственно перед элементом, который будет возвращен next(), если таковой имеется, и после элемента, который будет возвращен previous(), если таковой имеется. (Если список не содержит элементов, новый элемент становится единственным элементом в списке.) Новый элемент вставляется перед неявным курсором: последующий вызов next не будет затронут, а последующий вызов previous вернет новый элемент . (Этот вызов увеличивает на единицу значение, которое будет возвращено вызовом до nextIndex или previousIndex.)

Таким образом, чередующиеся вызовы previous() и add() будут сохранять значения вставки в одной и той же позиции в списке и, следовательно, никогда не завершатся (пока не закончится память).

Чтобы показать, что происходит, попробуйте этот код:

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", "^");
}

выход

   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
                ^
0 голосов
/ 17 января 2019

Ваш последний цикл выполняется бесконечно, потому что вы продолжаете добавлять элемент и проверять, имеет ли он предыдущий . Конечно, у него есть предыдущий, тот, который вы только что добавили.

Вы можете достичь того, что вы хотите: -

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

выход

[56, 0, 56, 1, 56, 2, 56, 3, 56, 4]
...