Почему list-iterator.next (); возвращается в позицию «нет текущего элемента», если она не повторяется несколько раз до конца? - PullRequest
0 голосов
/ 04 сентября 2018

Согласно документации Java:

ListIterator не имеет текущего элемента; его позиция курсора всегда лежит между элементом, который будет возвращен вызовом previous () и элемент, который будет возвращен вызовом next (). Итератор для списка длиной n имеет n + 1 возможных позиций курсора, как показано каретками (^) ниже:

Мой вопрос, например, предположим, что цикл while работает, и после нажатия 2 я вызываю метод

public void callNextElement(int choice, LinkedList<String> linkedList) {

    ListIterator<String> listIterator = linkedList.listIterator();
    if (choice == 2) {
        if (listIterator.hasNext()){
            listIterator.next();
            System.out.println("We have: " + listIterator.next());
        }
    }
}

Теперь, это напечатало бы первый элемент и вернулось к циклу while, чтобы получить ввод, теперь снова нажав 2, я получу первый элемент / запись списка. И если бы я сделал:

System.out.println("We have: " + listIterator.next());
System.out.println("We have: " + listIterator.next());
System.out.println("We have: " + listIterator.next());
System.out.println("We have: " + listIterator.next());
....

Это напечатало бы другие элементы в связанном списке

Итак, мои вопросы:

  1. Почему он не печатает 2-й элемент и т. Д. В методе, который я вызвал?

  2. Почему это работает только , если listiterator.next () вызывается последовательно, как я сделал, печатая их выше?

  3. Что произойдет, если listiterator фактически сохранит позицию следующего элемента, чтобы даже при вызове next() (без последовательности) он печатал следующий элемент? Не первый.

EDIT:

Я чувствую себя настолько глупо, но происходит ли сборка мусора в Java в моем вызове метода? Если да, то имеет смысл, почему он печатает 1-й элемент каждый раз. Я новичок в Java и совершенно забыл об этом ...

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Чтобы ответить на ваши вопросы, вы должны понимать, что Iterator запоминает свою позицию в Collection или Iterable, но только тот же экземпляр Iterator знает эту позицию (т.е. сколько раз Iterator.next() имеет был назван)

1) Почему он не печатает второй элемент и т. Д. В методе, который я вызвал?

ListIterator<String> listIterator = linkedList.listIterator();

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

2) Почему это работает, только если listiterator.next () вызывается в последовательности? как я сделал, напечатав их выше.

Как упомянуто выше, новый итератор всегда будет начинаться (или, более правильно, до) с первого элемента списка. Вызывая Iterator.next(), вы перемещаете итератор к следующему элементу списка. Если вы звоните next() несколько раз на один и тот же Iterator, вы будете перемещаться по всему списку, пока Iterator.hasNext() не вернет false. Если Iterator.hasNext() равно false, и вы продолжаете звонить Iterator.next(), то NoSuchElementException будет сброшено.

3) Что произойдет, если listiterator фактически сохранит позицию следующего элемента, чтобы, даже если next () вызывался (без последовательности), он печатал следующий элемент? Не первый.

Я думаю, что на это уже ответили выше?!

Вы можете изменить свой метод так, чтобы он принимал Iterator в качестве аргумента вместо списка следующим образом:

public void callNextElement(int choice, ListIterator<String> listIterator) {
    if (choice == 2) {
        if (listIterator.hasNext()){
            listIterator.next()
            System.out.println("We have: " + listIterator.next());
        }
    }
}

Этот метод будет вызываться так:

ListIterator<String> listIterator = linkedList.listIterator();
while (condition == true) {
    callNextElement(choice, listIterator);
}

Таким образом, вы всегда будете передавать одинаковые Iterator методу callNextElement и последовательно продвигать позицию этого итератора.

И нет, это никак не связано с сборкой мусора.

0 голосов
/ 04 сентября 2018

Каждый итератор списка имеет свою независимую позицию в списке. Каждый раз, когда вы звоните listIterator(), вы получаете новый итератор, который начинается в начале списка.

ListIterator<String> listIterator = linkedList.listIterator();

Если вы хотите перебрать последовательные элементы, вам нужно один раз вызвать listIterator() и сохранить итератор где-нибудь, чтобы его можно было повторно использовать.

...