线程 "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);