线程 "main" java.util.ConcurrentModificationException 中出现异常,不知道为什么
Exception in thread "main" java.util.ConcurrentModificationException, Not sure why
这个 'playlist' class 应该能够跳过重播并返回播放列表中的歌曲,该播放列表是歌曲的链接列表,这是另一个 class,但是我得到了线程“main”中的错误异常 java.util.ConcurrentModificationException
这是我写的播放列表class:(先谢谢你)
package com.sulay;
import java.util.LinkedList;
import java.util.ListIterator;
public class Playlist {
private LinkedList<Song> songs;
private ListIterator<Song> listIterator;
private boolean goingForward = true;
public Playlist() {
this.songs = new LinkedList<>();
this.listIterator = this.songs.listIterator();
}
public LinkedList<Song> getSongs() {
return this.songs;
}
public void addSong(Song song) {
if(!checkSong(song)) {
this.songs.add(song);
System.out.println("Song " + song.getTitle() + " added");
} else {
System.out.println("Song " + song.getTitle() + " already exists");
}
}
public boolean checkSong(Song song) {
for (Song currentSong : songs) {
if (currentSong.equals(song)) {
return true;
}
}
return false;
}
public void skipSong() {
if (listIterator.hasNext()) {
if (!goingForward) {
listIterator.next();
goingForward = true;
}
System.out.println(listIterator.next() + " now playing");
} else {
System.out.println("No next song");
}
}
public void previousSong() {
if (listIterator.hasNext()) {
if (goingForward) {
listIterator.next();
goingForward = false;
}
System.out.println(listIterator.previous() + " now playing");
} else {
System.out.println("No previous song");
}
}
public void replaySong() {
if (goingForward){
goingForward = false;
System.out.println("Playing " + listIterator.previous());
} else if (!goingForward) {
goingForward = true;
listIterator.next();
System.out.println("Playing " + listIterator.previous());
}
}
public void displaySongs() {
for (Song currentSong : songs) {
System.out.println("Name: " + currentSong + " Album: " + currentSong.getAlbum());
}
}
}
如果允许添加新歌,listIterator的状态与列表不同步。所以它现在可能会在任何时候抛出一个 ConcurrentModificationException
最好的方法是在初始化后不要公开或使用列表。因此,在您开始播放播放列表后,您将无法添加或删除它。或者你可以只使用一个数组列表,它是 RandomAccess
,即它支持恒定时间 get
方法和一个索引变量。这不需要任何列表迭代器。
请记住,您是通过 getSongs
方法公开可变列表。为了安全起见,使它的 return 值 List<Song>
和 return this
return new ArrayList<>(songs);
这个 'playlist' class 应该能够跳过重播并返回播放列表中的歌曲,该播放列表是歌曲的链接列表,这是另一个 class,但是我得到了线程“main”中的错误异常 java.util.ConcurrentModificationException 这是我写的播放列表class:(先谢谢你)
package com.sulay;
import java.util.LinkedList;
import java.util.ListIterator;
public class Playlist {
private LinkedList<Song> songs;
private ListIterator<Song> listIterator;
private boolean goingForward = true;
public Playlist() {
this.songs = new LinkedList<>();
this.listIterator = this.songs.listIterator();
}
public LinkedList<Song> getSongs() {
return this.songs;
}
public void addSong(Song song) {
if(!checkSong(song)) {
this.songs.add(song);
System.out.println("Song " + song.getTitle() + " added");
} else {
System.out.println("Song " + song.getTitle() + " already exists");
}
}
public boolean checkSong(Song song) {
for (Song currentSong : songs) {
if (currentSong.equals(song)) {
return true;
}
}
return false;
}
public void skipSong() {
if (listIterator.hasNext()) {
if (!goingForward) {
listIterator.next();
goingForward = true;
}
System.out.println(listIterator.next() + " now playing");
} else {
System.out.println("No next song");
}
}
public void previousSong() {
if (listIterator.hasNext()) {
if (goingForward) {
listIterator.next();
goingForward = false;
}
System.out.println(listIterator.previous() + " now playing");
} else {
System.out.println("No previous song");
}
}
public void replaySong() {
if (goingForward){
goingForward = false;
System.out.println("Playing " + listIterator.previous());
} else if (!goingForward) {
goingForward = true;
listIterator.next();
System.out.println("Playing " + listIterator.previous());
}
}
public void displaySongs() {
for (Song currentSong : songs) {
System.out.println("Name: " + currentSong + " Album: " + currentSong.getAlbum());
}
}
}
如果允许添加新歌,listIterator的状态与列表不同步。所以它现在可能会在任何时候抛出一个 ConcurrentModificationException
最好的方法是在初始化后不要公开或使用列表。因此,在您开始播放播放列表后,您将无法添加或删除它。或者你可以只使用一个数组列表,它是 RandomAccess
,即它支持恒定时间 get
方法和一个索引变量。这不需要任何列表迭代器。
请记住,您是通过 getSongs
方法公开可变列表。为了安全起见,使它的 return 值 List<Song>
和 return this
return new ArrayList<>(songs);