简体   繁体   中英

when remove an element of ArrayList from inside for each loop. its break the loop

when remove an element of ArrayList from inside foreach loop. its break the loop.
throw ConcurrentModificationException
My question is why its break the loop.

Code.

ArrayList gStudyLst=getLst();
    int recordCount=0;
    for(String study : gStudyLst){
        if(++recordCount < 10){
            if(generateFile(study)){
                gStudyLst.remove(study); // there its break throw ConcurrentModificationException
            }else{
                System.out.println("File not generated"):
                gStudyLst.clear();
                return false;
                }
            }
        }else{
            return true;
        }   
    }

Use Iterator to avoid ConcurrentModificationException .

Java doc of the Iterator interface says:

Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.

Here is an example:

Iterator<String> iter = myArrayList.iterator();

while (iter.hasNext()) {
    String str = iter.next();

    if (someCondition)
        iter.remove();
}

It is because "The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future."

See http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html for details.

for each loop is just used to iterate through the values of the arraylist. If you want to remove values inside the loop, use iterator as shown below

for (Iterator iterator = gStudyLst.iterator(); iterator.hasNext();) {
            String study = (String) iterator.next();

}

The enhanced for statement has the form:

for ( Type Identifier : Expression ) Statement

The enhanced for statement is equivalent to a basic for statement of the form:

for (I iter = Expression.iterator(); iter.hasNext(); ) { Type Identifier = iter.next(); Statement } for (I iter = Expression.iterator(); iter.hasNext(); ) { Type Identifier = iter.next(); Statement } From javaDoc:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException

So instead of using forEach use Iterater and modify your List using the iterator's own remove or add methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM