【问题标题】:ConcurrentModificationException in Java List when using Object and Duplicate List [duplicate]使用对象和重复列表时 Java 列表中的 ConcurrentModificationException [重复]
【发布时间】:2017-02-09 18:42:11
【问题描述】:

我正在使用 Java 来迭代列表并根据某些标准对其进行更新。但是由于它将为此使用重复列表提供ConcurrentModificationExceptionim,但这仍然提供相同的异常。

我有一个名为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 个存储,每个对象都有单独的文件夹。我使用 for 循环并调用 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;
        }
    }
}

但这在我在updateFileList() 函数中使用的Enhanced For Loop 中提供了ConcurrentModificationException。在增强的 for 循环中,我通过删除不需要的文件来更新 this.getFilesList() 列表,并使用重复列表 files 进行迭代。那为什么我得到ConcurrentModificationException 异常?我是不是做错了什么?

【问题讨论】:

    标签: java list function class arraylist


    【解决方案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;
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      您也可以使用 ListIterator 而不是使用 for each 。并使用 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

      【讨论】:

        【解决方案3】:

        您在遍历列表时从列表中删除元素。

        尝试将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);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-10
          • 2015-12-04
          • 2013-12-01
          相关资源
          最近更新 更多