Переход назад в ListIterator БЕЗ дублирования последнего показанного элемента

Я изучаю Java с нуля, и мне это очень нравится, но у меня есть небольшая проблема, которую я не могу понять. Следующий код работает, я его тестировал, и дело в том, что когда пользователь идет назад по списку, последний вывод не должен дублироваться. И вот мой вопрос: почему (!goingForward) указывает на .next, а не наоборот?

public static void visit(LinkedList<String> linkedList) {

    ListIterator<String> listIterator = linkedList.listIterator();
    boolean quit = false;
    boolean goingForward = true;
    Scanner scanner = new Scanner(System.in);

    if (linkedList.isEmpty()) {
        System.out.println("No cities to visit");
    } else {
        printMenu();
    }
    while (!quit) {
        int actions = scanner.nextInt();
        scanner.nextLine();
        switch (actions) {
            case 0:
                printMenu();
                break;
            case 1:
                if (!goingForward) {
                    if (listIterator.hasNext()) {
                        listIterator.next();
                    }
                goingForward = true;

                }
                if (listIterator.hasNext()) {
                    System.out.println("Now visiting: " + listIterator.next());
                } else {
                    System.out.println("Reached the end of the list");
                    goingForward = false;
                }
                break;
            case 2:
                if (goingForward) {
                    if (listIterator.hasPrevious()) {
                        listIterator.previous();
                    }
                    goingForward = false;
                }
                if (listIterator.hasPrevious()) {
                    System.out.println("Now visiting: " + listIterator.previous());
                } else {
                    System.out.println("We are at the start of the list");
                    goingForward = true;
                }
                break;
            case 3:
                System.out.println("Thanks for using the app");
                quit = true;
                break;
        }

    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это делается для того, чтобы избежать повторного посещения последнего города при смене направления. Попробуйте, что произойдет, если вы удалите эту логику:

public class ListIteratorDemo {
  public static void main(String args[]) throws Exception {
    LinkedList<String> cities = new LinkedList<>();
    cities.add("A");
    cities.add("B");
    cities.add("C");
    visit(cities);
  }

  public static void visit(LinkedList<String> linkedList) {

    ListIterator<String> listIterator = linkedList.listIterator();
    boolean quit = false;
    //    boolean goingForward = true;
    Scanner scanner = new Scanner(System.in);

    if (linkedList.isEmpty()) {
      System.out.println("No cities to visit");
    }
    else {
      printMenu();
    }

    while(!quit) {
      int actions = scanner.nextInt();
      scanner.nextLine();
      switch(actions) {
        case 0: {
          printMenu();
          break;
        }
        case 1: {
          //          if (!goingForward) {
          //            if (listIterator.hasNext()) {
          //              listIterator.next();
          //            }
          //            goingForward = true;
          //          }

          if (listIterator.hasNext()) {
            System.out.println("Now visiting: " + listIterator.next());
          }
          else {
            System.out.println("Reached the end of the list");
            //            goingForward = false;
          }
          break;
        }
        case 2: {
          //          if (goingForward) {
          //            if (listIterator.hasPrevious()) {
          //              listIterator.previous();
          //            }
          //            goingForward = false;
          //          }

          if (listIterator.hasPrevious()) {
            System.out.println("Now visiting: " + listIterator.previous());
          }
          else {
            System.out.println("We are at the start of the list");
            //            goingForward = true;
          }
          break;
        }
        case 3: {
          System.out.println("Thanks for using the app");
          quit = true;
          break;
        }
      }
    }
  }

  private static void printMenu() {
    System.out.println("0=menu, 1=next, 2=previous, 3=quit");
  }
}

Я предполагаю, что это должно научить позиции курсоров ListIterator:

О вашем вопросе: если вы наберете 1 (вперед) и ранее двигались назад (!goingForward), курсор будет находиться слева от последнего посещенного города. Его необходимо сместить вправо от последнего посещенного города, чтобы избежать его повторного посещения при движении вперед (вызов следующего).

Спасибо за Ваш ответ! Я действительно борюсь с этой концепцией, так как не понимаю, что случай 1 - это возможность двигаться вперед, однако оператор «if» говорит (!goingForward) call listiterator.next .... зачем вызывать .next, а не . предыдущий? скажем, я только что вывел элемент 1, поэтому итератор находится между элементами 1 и 2, теперь идет назад, но я вызываю .next, почему бы не .previous? логика мне кажется обратной.

storok 28.12.2020 10:49

Я пытался объяснить это в последнем абзаце. Переменная goingForward используется для сохранения направления последнего движения. Операторы if проверяют, изменило ли текущее движение направление (по сравнению с последним движением).

Reto Höhener 29.12.2020 15:17

Представьте, что вы находитесь между 1 и 2. Затем двигайтесь назад: вы посещаете 1 и теперь находитесь между 0 и 1. Теперь вы снова идете вперед. Это случай переключения 1: пропустить следующий элемент 1, а затем снова перейти к элементу 2, приземлившись между 2 и 3.

Reto Höhener 29.12.2020 15:20

Большое спасибо! Это был не ты, это был я. Ваше объяснение безупречно, мне просто потребовалось некоторое время, чтобы обработать его, поскольку я думал о процессе в обратном направлении. В конце каждого переключателя я устанавливаю для goForward значение true или false, и это настраивает весь процесс. Еще раз спасибо за вашу помощь! Я собираюсь узнать о BinaryTrees, а затем и о дженериках. Это потрясающее путешествие, мне очень нравится!

storok 06.01.2021 10:45

Рад слышать :) Пожалуйста, примите ответ, если он решил ваш вопрос. Удачи!

Reto Höhener 06.01.2021 10:48

Другие вопросы по теме