2016-10-01 2 views
0

Я использую Java для перебора списка и обновления его на основе определенных критериев. Но так как он предоставит ConcurrentModificationException im, используя для этого дублирующий список, но это все равно обеспечивает одно и то же исключение.ConcurrentModificationException в Java List при использовании Object и Duplicate List

У меня есть класс с именем Storage, который обозначает виртуальное хранилище, которое представлено как папка (одна папка для одного хранилища), и этот класс содержит атрибут fileList, который обозначает список файлов, которые он содержит (внутри папки). Класс, как указано ниже,

public class Storage 
{ 
    // List of files in storage 
    private List<File> fileList = new ArrayList<File>(); 

    // Occupied size in MB 
    private double occupiedStorage; 

    // Location of storage folder 
    private String location; 

    public Storage(String loca) // Create a storage 
    { 
     this.location = loca; 
     this.occupiedSize = 0; 
    } 

    public addFile(File f) // Add file to storage 
    { 
     // Copy the file to folder in location 'this.location' 
     this.fileList.add(f); 
     this.occupiedSize = this.occupiedSize + f.length()/1048576.0; 
    } 

    public List<File> getFilesList() // Get list of files in storage 
    { 
     return this.filesList; 
    } 

    public double getOccupiedSize() // Get the occupied size of storage 
    { 
     return this.occupiedSize; 
    } 
} 

Я создал в общей сложности 10 устройств хранения с использованием 10 объектов, и каждый из них имеет отдельные папки. Я добавил много разных файлов во все папки, используя для цикла, и вызвал функцию this.addFile(f).

Позже я хочу, чтобы удалить только определенные файлы из определенных хранилищ, которые удовлетворяют определенные критерии, и я добавил следующую функцию удаления в Storage класса,

public void updateFileList() 
{ 
    List<File> files = new ArrayList<File>(); 
    files = this.getFilesList(); 
    for (File f : files) 
    { 
     if (/*Deletion criteria satisfied*/) 
     { 
      f.delete(); 
      this.getFilesList().remove(f); 
      this.occupiedSize = this.occupiedSize - f.length()/1048576.0; 
     } 
    } 
} 

Но это дает ConcurrentModificationException в Enhanced For Loop, что я нахожусь используя функцию updateFileList(). В расширенном цикле я обновляю список this.getFilesList(), удаляя ненужный файл, и итерация выполняется с использованием дублирующего списка files. Тогда почему я получаю исключение ConcurrentModificationException ?? Я делаю что-то неправильно?

ответ

1

Вы не можете удалить элемент из списка с remove() во время итерации. Но вы можете сделать это, используя итератор:

public void updateFileList() { 
     List<File> files = this.getFilesList(); 
     Iterator<File> iter = files.iterator(); 
     while (iter.hasNext()) { 
      File f = iter.next(); 
      if (/*Deletion criteria satisfied*/) 
      { 
       f.delete(); 
       iter.remove(); 
       this.occupiedSize = this.occupiedSize - f.length()/1048576.0; 
      } 
     } 
    } 
0

Вы удаляете элемент из списка, итерации по списку.

Попробуйте изменить метод getFilesList() от

public List<File> getFilesList() // Get list of files in storage 
{ 
    return this.filesList; 
} 

в

public List<File> getFilesList() // Get list of files in storage 
{ 
    return new ArrayList<File>(this.filesList); 
} 
1

Вы также можете использовать ListIterator, а не использовать для каждого. и используйте метод iterator.remove, чтобы удалить файл из списка.

public void updateFileList() 
{ 
    List<File> files = new ArrayList<File>(); 
    files = this.getFilesList(); 
    Iterator<File> it = files.iterator(); 
     while (it.hasNext()) { 

      if (deletion condition) { 

       it.remove(); 

      } 
     } 
} 

также читать о отказоустойчивость быстро и отказоустойчивая итератора в Java ссылке здесь fail-fast and fail-safe iterator in java

Смежные вопросы