【问题标题】:ArrayList iteration gives exception java.util.ConcurrentModificationExceptionArrayList 迭代给出异常 java.util.ConcurrentModificationException
【发布时间】:2013-11-13 20:26:42
【问题描述】:

java.util.ConcurrentModificationException: "如果方法检测到对象的并发修改是不允许的,则该异常可能会被抛出。"

知道为什么我的 set 方法会出现此异常吗?

private ArrayList<Double> voltagesList = new ArrayList<Double>();
private ArrayList<String> devicesList = new ArrayList<String>();

public void setVoltage(String device, double voltage) { 
    for(String d: devicesList){
            if(d.equals(device)){
                voltagesList.set(devicesList.indexOf(device), voltage);
        }
            else{
                voltagesList.add(voltage);
                devicesList.add(device);
            }
    }
}

【问题讨论】:

  • 不是迭代导致异常。
  • 您在迭代时添加,这是一个错误,因为我假设您只想在未找到时添加。

标签: java exception arraylist


【解决方案1】:

您应该使用地图,而不是使用一对列表。

private final Map<String, Double> deviceVoltageMap = new HashMap<>();

public void setVoltage(String device, double voltage) { 
    deviceVoltageMap.put(device, voltage);
}

【讨论】:

  • 太棒了,感谢您的提示。还有一个问题 - 我将如何在 Map 中添加值?
  • @Ian put 将插入或替换。
  • 我的意思是在一个单独的函数中,我希望在设置它们之后添加存储在地图中的值。
  • @Ian 你的意思是你想为同一个设备提供多个电压吗?在这种情况下使用MultiMapMap&lt;String, List&lt;Double&gt;&gt;
【解决方案2】:
ListIterator<String> iter = devicesList.listIterator();
while(iter.hasNext()) {
   String d = iter.next();
   if(d.equals(device)){
       voltagesList.set(devicesList.indexOf(device), voltage);
   }
      else{
         voltagesList.add(voltage);
         iter.add(device);
   }
}

【讨论】:

    【解决方案3】:

    是的,你得到这个的原因是devicesList.add(device);你正在添加到这个列表中你正在迭代它。您不能在 ArrayList 的 foreach 循环中执行此操作。

    我通常做的是将要添加的内容收集到一个单独的临时列表中,然后在循环之外我调用addAll。这是一个例子:

    package com.sandbox;
    
    import java.io.FileNotFoundException;
    import java.util.ArrayList;
    
    public class Sandbox {
    
        public static void main(String[] args) throws FileNotFoundException {
            Sandbox sandbox = new Sandbox();
            sandbox.devicesList.add("foo");
            sandbox.setVoltage("bar", 1.0);
        }
    
        private ArrayList<Double> voltagesList = new ArrayList<Double>();
        private ArrayList<String> devicesList = new ArrayList<String>();
    
        public void setVoltage(String device, double voltage) {
            ArrayList<String> newDevicesList = new ArrayList<String>();
            for (String d : devicesList) {
                if (d.equals(device)) {
                    voltagesList.set(devicesList.indexOf(device), voltage);
                } else {
                    voltagesList.add(voltage);
                    newDevicesList.add(device);
                }
            }
            devicesList.addAll(newDevicesList);
        }
    
    }
    

    【讨论】:

    • 在这种情况下,如何添加到列表中?
    • 好吧,你可以这样做,但只能使用支持add 操作的显式ListIterator。我会添加一个答案。
    • @Ian 一种方法是将值存储在临时 Lists 中,并在所需列表中使用 List#addAll
    • @Ian 但再次查看您发布的代码,似乎您遇到了设计问题。为什么要并行使用两个Lists 而不是List&lt;Device&gt;
    【解决方案4】:

    您无法修改正在迭代的集合,除非您使用迭代器进行迭代并调用 iterator.remove() 来修改它。

    您可以创建一个新的空集合并向其中添加元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多