1

java.util.ConcurrentModificationException: "This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible."

Any idea why my set method gives this exception?

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);
            }
    }
}
2
  • It's not the iteration that's causing the exception. Commented Nov 13, 2013 at 20:27
  • 1
    you are adding while iterating which is a bug because I assume you only want to add if it is not found. Commented Nov 13, 2013 at 20:37

4 Answers 4

4

Instead of using a pair of Lists you should be using a Map.

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

public void setVoltage(String device, double voltage) { 
    deviceVoltageMap.put(device, voltage);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Brilliant, thanks for the tip. One more question- how would I go about adding the values in a Map?
@Ian put will insert or replace.
I mean in a separate function, I wish to add the values stored in the Map, after setting them.
@Ian Do you means you want multiple voltages for the same device? In that case use MultiMap or Map<String, List<Double>>
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);
   }
}

Comments

2

Yes the reason you're getting this is devicesList.add(device); You are adding to this list as you're iterating it. You can't do that in a foreach loop on an ArrayList .

What I usually do is collect the things I want to add in a separate, temporary list and then outside of the loop I call addAll. Here's an example:

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);
    }

}

4 Comments

In this case, how can I add to the list?
Well, you can do that, but only using an explicit ListIterator that supports an add operation. I will add an answer.
@Ian one way could be storing the values in temporary Lists and the using List#addAll in your desired lists.
@Ian but giving a second look at your posted code, seems like you have a design issue. Why are you using two Lists in parallel instead of using a List<Device>?
1

You can't modify a collection you're iterating over, unless you're iterating with iterator and calling iterator.remove() to modify it.

You can create a new empty collection and add elements to it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.