简体   繁体   中英

using a list iterator to iterate through Linked List Java

For this program we are to create a LinkedList of type Song. Song contains two instance variables, title and artist. The user is prompted to enter a command (either add, remove, print, or quit). I am having problems with the remove method. We are not allowed to use a regular or enhanced for loop to iterate through the LinkedList. He says for our remove method, we are supposed to use the ListIterator remove(), not the LinkedList remove(). Here's what I got for the loop.

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)) {
      .
      .
      .
   }
}

Every time I run this I get a java.util.ConcurrentModificationException error and I am not sure what this is or how to fix it. Any help? I know the problem is in the remove method.

The problem lies when you initialized your ListIterator<Song> iter what happen is that you only initialized it once therefore if you add a new item within your LinkedList the iterator will have none therefore it couldn't find any elements in the list and resulting to an error..

What you need to do it to initialized the ListIterator every-time you remove an element.

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

EDIT: My first answer was wrong, now it is fixed.

The java.util.ConcurrentModificationException is an exception thrown when something changes your list while you are iterating. In your code, it was a bit hard to detect (for me, others would probably detect quickly), but we have to remeber that you start iterating at the moment you create an iterator. When you execute list.iterator() you get yourself an iterator, starting from the "first" element, ready to iterate through the list. The problem is, you created the iterator at the beginning of your code, when the list was empty. Therefore, at the first time you tried to loop through it, of course the list had changed (some elements were added). Then you got that exception.

(Usually, that exception is raised when elements are deleted using List.remove() inside a loop, that's why I had a wrong impression at a first glance, and gave a totally wrong answer - sorry about that).

This would be your fixed code:

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")) {
      .
      .
      .
   }
}

You also have a few syntax errors. For example, you had new songList.listIterator() , while the correct would be just songList.listIterator() , because that function already returns the iterator, ready for usage.

Also, you forgot doublequotes on each of the tests for user input (QUIT, ADD, REMOVE, etc).

Java iterator classes are fail-fast. If modification of the list is attempted while it is being iterated through , an exception will be thrown. The iterator actions must be stopped first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM