Java parallel modification exception error

I play with some code for my college course and changed the method from

public boolean removeStudent(String studentName) { int index = 0; for (Student student : students) { if (studentName.equalsIgnoreCasee(student.getName())) { students.remove(index); return true; } index++; } return false; } 

To:

 public void removeStudent(String studentName) throws StudentNotFoundException { int index = 0; for (Student student : students) { if (studentName.equalsIgnoreCase(student.getName())) { students.remove(index); } index++; } throw new StudentNotFoundException( "No such student " + studentName); } 

But the new method continues to give a parallel modification error. How can I get around this and why is this happening?

+8
java arraylist
source share
8 answers

This is because you keep navigating the list after you remove() .

You both read and write to the list, which violates the iterator contract that underlies the foreach loop.

Use Iterator.remove()

 for(Iterator<Student> iter = students.iterator(); iter.hasNext(); ) { Student student = iter.next(); if(studentName.equalsIgnoreCase(student.getName()) { iter.remove(); } } 

It is described as follows:

Returns the next item in an iteration.

NoSuchElementException if the iteration has no more elements.

You can use Iterator.hasNext() to check for the next element.

+17
source share
Design

foreach uses the basic Iterator .

In the second method, you continue to iterate even after removing an item from the list. This leads to what you see. Take a look at this statement, taken from the ConcurrentModificationException documentation:

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.

+1
source share

This error occurs because you are trying to resize a collection during iteration. If you have 10 students, you start your loop expecting to go through 10 iterations. When you delete a student, how many iterations still need to go? The answer, obviously, depends on where you removed your student from the list and where you are currently in your lawsuit. Obviously, java cannot know this.

To get around this, you should use an iterator. You can accomplish this as follows:

 Iterator<Student> studentsIterator; for(studentsIterator = students.iterator(); studentsIterator.hasNext();) { Student student = studentsIterator.next(); if(student... /* condition */) { studentIterator.remove(); //This removes student from the collection safely } } 
0
source share

You are not allowed to remove an item from the students collection, iterating through it.

This exception may be caused by methods that have detected a simultaneous modification of an object, if such a modification is unacceptable.

For example, one thread is usually not allowed to modify the collection, while another thread iterates through it. In general, the iteration results in this case are undefined.

http://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html

Try switching to

 Iterator<Student> itr = students.iterator(); while (itr.hasNext()) { Student student = itr.next(); if (studentName.equalsIgnoreCase(student.getName())) { itr.remove(); } } 
0
source share

If you want to remove inside the loop, you must use an iterator and its remove method

 public boolean removeStudent(String studentName) { Iterator<Student> itS = students.iterator(); while(itS.hasNext()) { Student student = itS.next(); if (studentName.equalsIgnoreCasee(student.getName())) { itS.remove(); return true; } } return false; } 
0
source share

You are not allowed to remove an item from your collection while you iterate over it. The iterator detects structural changes during its use and throws an exception. Many collections are implemented in this way.

Use an iterator instead:

  Iterator<Student> it = students.iterator(); while (it.hasNext()) { Student student = it.next(); if (studentName.equalsIgnoreCase(student.getName())) { it.remove(); return true; } } return false; 
0
source share

You should not remove objects from the collection when using for each statement - this will lead to exceptions, since your iterator encounters a modified collection during its iterations. (for loop) either use a regular loop (for int i = 0; i <100; i ++) etc ... or save the objects in the list and delete them outside the for loop.

In addition, you delete the object by index, where the index is: 0, 1, 2 but the index should act like the index of a student.

0
source share

you can avoid a simultaneous modification error by buying only a loop break after deleting an element or if the method has a return type, return a value after deleting the element.

0
source share

All Articles