从ArrayList中删除对象会导致ConcurrentModificationException

时间:2015-02-27 02:05:24

标签: java file-io arraylist concurrentmodification

我创建了一个Song类,其中包含歌曲(标题,艺术家,专辑)的数据成员。我已经有一个.txt文件,其中包含存储在数组列表中的不同歌曲。在我的主要课程中,其中一个功能是允许用户通过搜索歌曲标题来删除歌曲。

我的问题是,在迭代for循环并尝试删除该位置的索引时,我收到ConcurrenModificationException。我理解在迭代时尝试删除对象是导致此异常的原因。我一直试图找出一种方法来跟踪歌曲所在的索引,然后在完成迭代后删除它,但我需要一些帮助来解决这个问题。

这是我的Song类,包含Constructor和Get / Set Methods

public class Song {
    //Declaring all data members.
    private String title;
    private String artist;
    private String album;
    private String length;
    private static int songCounter = 0;

    //Constructors for Song class.      
    public Song(String title, String artist, String album, String length){
        this.title = title;
        this.artist = artist;
        this.album = album;
        this.length = length;
        songCounter++;
    }
    //Get and Set methods 
    public String getTitle(){
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getArtist(){
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getAlbum(){
        return album;
    }

    public void setAlbum(String album){
        this.album = album;
    }

    public String getLength(){
        return length;
    }

    public void setLength(String length){
        this.length = length;
    }

    public static int getSongCounter(){
        return songCounter;
    }
    //Overriding the toString() function.
    public String toString(){
        return title +" "+artist+" "+album+" "+length;
    }
}

从.txt文件读取并包含抛出异常的删除方法的主类

public class Library {

public static void main(String[] args) {
    ArrayList <Song> songList = new ArrayList <Song> ();
    boolean testInput = true;

    try{
        Scanner read = new Scanner (new File("SongList.txt"));
        do{
            String line = read.nextLine();
            String [] tokens = line.split(",");
            songList.add(new Song(tokens[0], tokens[1], tokens[2], tokens[3]));
        }while(read.hasNext());
        read.close();
    }catch (FileNotFoundException e){
        System.out.println("File not found.");
    }

    while ( testInput ){
        System.out.println("\nSelect a Function");
        System.out.println("1. Search Song");
        System.out.println("2. Add Song");
        System.out.println("3. Delete Song");
        System.out.println("4. Display Songs");
        System.out.println("5. Quit");

        switch (MenuInputCheck(1, 5)){

        case 1: searchSong(songList);
                break;
        case 2: addSong(songList);
                break;
        case 3: deleteSong(songList);
                break;
        case 4: displaySong(songList);
                break;
        case 5: testInput = false;
                break;
        }
    }
}
public static void deleteSong(ArrayList <Song> songList){
    Scanner input = new Scanner(System.in);
    System.out.println("How would you like to delete a song?");
    System.out.println("A. Song Title");

    boolean found = false;
    char menuOption = input.nextLine().charAt(0);

    switch (menuOption){

    case 'A':
    case 'a':
            System.out.print("Enter song title: ");
            String searchTitle = input.nextLine();
            for (Song i : songList){
                if (i.getTitle().equals(searchTitle)){
                    songList.remove(i);
                    found = true;
                }
            }
            if ( found != true ){
                System.out.println("Song does not exist.");
            }
            break;
        }
}

1 个答案:

答案 0 :(得分:2)

你永远不应该这样做:

for (Song i : songList){
    ...         
    songList.remove(i);
    ...
}

在迭代它时从集合中删除项需要迭代器。这样做是这样的:

for (Iterator<Song> iterator = songList.iterator();iterator.hasNext();) {
    Song i = iterator.next();
    ...
    iterator.remove();
    ...
}