2015-05-02 3 views
0

Для этой программы мы должны создать LinkedList типа Song. Песня содержит две переменные экземпляра, название и исполнитель. Пользователю предлагается ввести команду (добавить, удалить, распечатать или выйти). У меня проблемы с методом remove. Нам не разрешено использовать регулярный или расширенный цикл для итерации через LinkedList. Он говорит, что для нашего метода удаления мы должны использовать ListIterator remove(), а не LinkedList remove(). Вот что я получил за цикл., используя итератор списка для итерации по связанному списку Java

Scanner input = new Scanner (System.in); 
LinkedList<Song> songList = new LinkedList<Song>(); 
ListIterator<Song> iter = new songList.listIterator(); 
boolean done = false; 

while (!done) { 
    System.out.print ("Please enter a command (add, remove, print or quit): "); 
    String command = input.nextLine(); 
    if (command.equals(QUIT)) { 
    // If quit, then exit the loop. 
    done = true; 
    } else if (command.equals(ADD)) { 
    addSong(songList, input); 
    songCount++; 
    } else if (command.equals(REMOVE)) { 
    System.out.print ("Please enter song title: "); 
    String removeTitle = input.nextLine(); 

    while (iter.hasNext()) { 
     String checkSong = iter.next().getTitle(); 
     if (removeTitle.equals(checkSong)) { 
     iter.remove(); 
     } 
    } 
    } else if (command.equals(PRINT)) { 
     . 
     . 
     . 
    } 
} 

Каждый раз, когда я запускаю это я получаю ошибку java.util.ConcurrentModificationException и я не уверен, что это и как это исправить. Любая помощь? Я знаю, что проблема заключается в методе удаления.

+0

действительно ли это происходит при первом удалении? –

+0

Да, в первый раз, когда я вызываю удаление, это дает мне эту ошибку. Я пробовал это только с одной песней, думая, что это может быть что-то со списком, затем я попробовал это с 4-5 песнями и до сих пор получил эту ошибку. – GenericUser01

+0

Это происходит без добавления? Я бы создал итератор только тогда, когда функция удаления обнаружена (и отменит ее впоследствии). Не держите его в нескольких добавлениях. – eckes

ответ

0

EDIT: Мой первый ответ был неправ, теперь это исправлено.

java.util.ConcurrentModificationException - исключение, созданное, когда что-то изменяет ваш список во время итерации. В вашем коде было немного сложно обнаружить (для меня, другие, вероятно, будут быстро обнаружены), но мы должны помнить, что вы набрали итерации на момент создания итератора. Когда вы выполняете list.iterator(), вы получаете себе итератор, начиная с «первого» элемента, готового к итерации по списку. Проблема в том, что вы создали итератор в начале вашего кода, когда список пуст. Поэтому, в первый раз, когда вы попытались пройти через него, конечно, список изменился (некоторые элементы были добавлены). Тогда вы получили это исключение.

(Как правило, это исключение возникает, когда элементы удаляются с использованием List.remove() внутри цикла, поэтому у меня возникло неправильное впечатление на первый взгляд и дал совершенно неправильный ответ - извините за это).

Это будет ваш фиксированный код:

Scanner input = new Scanner (System.in); 
LinkedList<Song> songList = new LinkedList<Song>(); 
ListIterator<Song> iter; 
boolean done = false; 

while (!done) { 
    System.out.print ("Please enter a command (add, remove, print or quit): "); 
    String command = input.nextLine(); 
    if (command.equals("QUIT")) { 
    // If quit, then exit the loop. 
    done = true; 
    } else if (command.equals("ADD")) { 
    addSong(songList, input); 
    songCount++; 
    } else if (command.equals("REMOVE")) { 
    System.out.print ("Please enter song title: "); 
    String removeTitle = input.nextLine(); 

    iter = songList.listIterator(); 
    while (iter.hasNext()) { 
     String checkSongTitle = iter.next().getTitle(); 
     if (removeTitle.equals(checkSongTitle)) { 
     iter.remove(); 
     } 
    } 
    } else if (command.equals("PRINT")) { 
     . 
     . 
     . 
    } 
} 

У вас также есть несколько синтаксических ошибок. Например, у вас было new songList.listIterator(), тогда как правильное было бы только songList.listIterator(), потому что эта функция уже возвращает итератор, готовый к использованию.

Кроме того, вы забыли двойные кавычки в каждом из тестов для ввода пользователем (QUIT, ADD, REMOVE и т. Д.).

+0

О, ладно.Наш профессор любит использовать константы для команд ввода, поэтому QUIT, ADD, REMOVE - это все строковые константы, которые содержат строку «add», «quit», «remove» и т. Д. – GenericUser01

+0

О, я вижу, это на самом деле отличная идея, Я поддерживаю его полностью. Я не думал об этом, когда отвечал. Я предлагаю вам придерживаться этой практики. Кстати, возможно, вы захотите добавить на вход пользователя .toUpperCase(), чтобы обнаружить «quit», а не только «QUIT». – Hamsterrific

+0

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

1

Проблема заключается при инициализации вашего ListIterator<Song> iter то, что произойдет в том, что вы только инициализируетесь один раз поэтому, если вы добавляете новый элемент в вашем LinkedList итератора не будет иметь ни поэтому он не мог найти какие-либо элементы в списке и в результате к ошибка.

Что вам нужно сделать, чтобы инициализировать ListIterator каждый раз, когда вы удаляете элемент.

else if (command.equals(REMOVE)) { 
    System.out.print ("Please enter song title: "); 
    String removeTitle = input.nextLine(); 

    ListIterator<Song> iter = songList.listIterator(); //initialize here 
    while (iter.hasNext()) { 
     String checkSong = iter.next().getTitle(); 
     if (removeTitle.equals(checkSong)) { 
     iter.remove(); 
     } 
    } 
    } 
-1

Классы итераторов Java не работают быстро. Если во время его повторного просмотра будет произведена модификация списка, будет выбрано исключение. Сначала необходимо остановить действия итератора.

Смежные вопросы