I keep getting java.util.concurrentmodificationexception .. How to fix this?

I am working on this piece of code. Here is the pseudo code of what I want:

a.check if the size of the partitions (which is a list) is 0.
b.if the size of the sections is 0, then automatically enrolls the student in the section by calling section.add (newSection)
c.else, if the size of the partitions is not zero, check for conflicts with the schedule

d. if there are no conflicts, then write the student to the section by calling section.add (newSection)
e.else do nothing

Java keeps throwing the error "java.util.concurrentmodificationexception" on me. I know I should not resize the ArrayList when moving the list, because it will change the iterator. Is there any other way to solve this problem ?: D

Many thanks. Your help is much appreciated. :)

public String enrollsTo(Section newSection){ StringBuffer result = new StringBuffer(); String resultNegative = "Failed to enroll in this section."; String resultPositive = "Successfully enrolled in section: " + newSection.getSectionName() + "."; int previousSectionSize = sections.size(); if(this.sections.isEmpty()){ this.sections.add(newSection); result.append(resultPositive); }else{ for(Iterator<Section> iterator = sections.iterator(); iterator.hasNext() ; ){ Section thisSection = iterator.next(); if(thisSection.conflictsDayWith(newSection)==false && thisSection.conflictsTimeWith(newSection)==false){ this.sections.add(newSection); //<-- i believe the problem lies here. result.append(resultPositive); } } } // if(this.sections.size() == previousSectionSize){ // result.append(resultNegative); // } return result.toString(); } 
+2
source share
6 answers

Do not sections.add(newSection) inside the for loop, as this is a modification of the collection that you are currently executing.

Also, would you like to check all sections before deciding whether to add newSection or not? Maybe something like this:

 boolean conflict = false; for (...) { if (/* check for conflict */) { conflict = true; break; } } if (!conflict) { sections.add(newSection); } 
+1
source

From javadoc for ConcurrentModificationException (my emphasis):

This exception can be selected by methods that detect simultaneous changes in the object, if such a modification is unacceptable.

For example, it is usually not allowed to modify one thread in a Collection while another thread iterates through it. In general, the results of iterations are undefined under these conditions. Some Iterator implementations (including all general ones intended for data collection provided by the JRE) may choose if this behavior is detected. Iterators that do this are known as fail-safe iterators because they do not work quickly and cleanly, but rather, at the risk of arbitrary, non-deterministic behavior for an indefinite time in the future.

Note that this exception does not always indicate that the object has been simultaneously changed by another thread. If one thread throws a sequence of method calls that violate the contract of the object, the object may throw this exception. For example, if thread modifies a collection directly while iterating through a collection with a fail-safe iterator, the iterator will throw this exception.

Please note that failed behavior cannot be guaranteed as it is, usually speaking, it is impossible to make any serious guarantees in the presence of unsynchronized parallel modification. Failure to quickly launch ConcurrentModificationException with maximum efficiency. Therefore, it would be wrong to write a program that depends on this exception for its correctness: ConcurrentModificationException should be used only to detect errors.

Potential solution: instead of adding directly to the list that you are repeating, add to the temporary list, and then when you have finished repeating, do addAll() .

0
source

During iteration of a collection, you cannot change it. String this.sections.add(newSection); throws an exception. You may need to use some logical marker to check the condition

 if(thisSection.conflictsDayWith(newSection)==false && thisSection.conflictsTimeWith(newSection)==false) 

After the for loop, if your boolean token is true, you can write

  this.sections.add(newSection); result.append(resultPositive); 
0
source

You are correct in your assumption

  this.sections.add(newSection); 

definitely the source of your problem.

The simplest solution: to have a logical idea of ​​the availability of the partition. Start by making it available. If there is a conflict in your iterator, set it to false. After the iterator, add a section if the section is available (boolean true).

0
source

ConcurrentModificationExceptions often occur when you modify a collection while iterating over its elements. Read this tutorial for more details and this old SO post. Why is this .next () throw java.util.ConcurrentModificationException?

0
source

I agree with @sudocode that you do not want to add newSection every time you find even a section that does not conflict. I would think that when you go through the code in your debugger, it will be obvious .;)

By the way, another (more obscure) way to do this without a flag

 CHECK: { for (...) { if (/* check for conflict */) break CHECK; } sections.add(newSection); } 
0
source

All Articles