简体   繁体   English

使用列表迭代器迭代链接列表Java

[英]using a list iterator to iterate through Linked List Java

For this program we are to create a LinkedList of type Song. 对于此程序,我们将创建一个Song类型的LinkedList。 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. 我在使用remove方法时遇到问题。 We are not allowed to use a regular or enhanced for loop to iterate through the LinkedList. 我们不允许使用常规或增强的for循环来遍历LinkedList。 He says for our remove method, we are supposed to use the ListIterator remove(), not the LinkedList remove(). 他说,对于我们的remove方法,我们应该使用ListIterator remove(),而不是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. 每次我运行此命令时,都会收到java.util.ConcurrentModificationException错误,并且不确定这是什么或如何解决。 Any help? 有什么帮助吗? I know the problem is in the remove method. 我知道问题出在remove方法中。

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.. 问题出在初始化ListIterator<Song> iter ,发生的事情是只初始化了一次,因此,如果在LinkedList添加新项,则迭代器将没有任何项,因此无法在列表中找到任何元素并导致一个错误..

What you need to do it to initialized the ListIterator every-time you remove an element. 每次删除元素时需要执行哪些操作来初始化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();
       }
     }
   }

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. java.util.ConcurrentModificationException是当您在迭代过程中更改列表时引发的异常。 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. 当执行list.iterator()您将获得一个从“第一个”元素开始的迭代器,可以迭代该列表。 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). (通常,在循环内使用List.remove()删除元素时会引发该异常,这就是为什么我乍看之下有一个错误的印象,并给出了完全错误的答案-对此感到抱歉)。

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. 例如,您有new songList.listIterator() ,而正确的只是songList.listIterator() ,因为该函数已经返回了迭代器,可以使用了。

Also, you forgot doublequotes on each of the tests for user input (QUIT, ADD, REMOVE, etc). 同样,您忘记了每个测试中用于用户输入的双引号(QUIT,ADD,REMOVE等)。

Java iterator classes are fail-fast. Java迭代器类是快速失败的。 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. 迭代器操作必须首先停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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