使用列表迭代器遍历链表 Java
using a list iterator to iterate through Linked List Java
对于这个程序,我们要创建一个 Song 类型的 LinkedList。 Song 包含两个实例变量,title 和 artist。提示用户输入命令(添加、删除、打印或退出)。我在使用 remove 方法时遇到问题。我们不允许使用常规或增强的 for 循环来遍历 LinkedList。他说对于我们的 remove 方法,我们应该使用 ListIterator remove(),而不是 LinkedList remove()。这是我得到的循环。
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 错误,我不确定这是什么或如何修复它。有什么帮助吗?我知道问题出在 remove 方法中。
问题在于当你初始化你的 ListIterator<Song> iter
时发生的事情是你只初始化了一次因此如果你在你的 LinkedList
中添加一个新项目迭代器将有 none 因此它在列表中找不到任何元素并导致错误..
每次删除元素时,您需要做什么来初始化 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();
}
}
}
编辑:我的第一个答案是错误的,现在已经修复了。
java.util.ConcurrentModificationException 是在您迭代时列表发生更改时抛出的异常。在你的代码中,它有点难以检测(对我来说,其他人可能会很快检测到),但我们必须记住你在创建迭代器的那一刻开始迭代。当您执行 list.iterator()
时,您会得到一个迭代器,从 "first" 元素开始,准备遍历列表。问题是,当列表为空时,您在代码的开头创建了迭代器。因此,在您第一次尝试遍历它时,列表当然已经更改(添加了一些元素)。然后你得到了那个例外。
(通常,当在循环中使用 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()
,因为该函数已经 returns 迭代器,可以使用了。
此外,您忘记了在每个用户输入测试(QUIT、ADD、REMOVE 等)上使用双引号。
Java 迭代器 类 是快速失败的。如果在遍历列表时尝试修改列表,将抛出异常。必须先停止迭代器操作。
对于这个程序,我们要创建一个 Song 类型的 LinkedList。 Song 包含两个实例变量,title 和 artist。提示用户输入命令(添加、删除、打印或退出)。我在使用 remove 方法时遇到问题。我们不允许使用常规或增强的 for 循环来遍历 LinkedList。他说对于我们的 remove 方法,我们应该使用 ListIterator remove(),而不是 LinkedList remove()。这是我得到的循环。
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 错误,我不确定这是什么或如何修复它。有什么帮助吗?我知道问题出在 remove 方法中。
问题在于当你初始化你的 ListIterator<Song> iter
时发生的事情是你只初始化了一次因此如果你在你的 LinkedList
中添加一个新项目迭代器将有 none 因此它在列表中找不到任何元素并导致错误..
每次删除元素时,您需要做什么来初始化 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();
}
}
}
编辑:我的第一个答案是错误的,现在已经修复了。
java.util.ConcurrentModificationException 是在您迭代时列表发生更改时抛出的异常。在你的代码中,它有点难以检测(对我来说,其他人可能会很快检测到),但我们必须记住你在创建迭代器的那一刻开始迭代。当您执行 list.iterator()
时,您会得到一个迭代器,从 "first" 元素开始,准备遍历列表。问题是,当列表为空时,您在代码的开头创建了迭代器。因此,在您第一次尝试遍历它时,列表当然已经更改(添加了一些元素)。然后你得到了那个例外。
(通常,当在循环中使用 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()
,因为该函数已经 returns 迭代器,可以使用了。
此外,您忘记了在每个用户输入测试(QUIT、ADD、REMOVE 等)上使用双引号。
Java 迭代器 类 是快速失败的。如果在遍历列表时尝试修改列表,将抛出异常。必须先停止迭代器操作。