0

From what I've read I understand that you get a ConcurrentModificationException when you try to edit a list while it's still being iterated.

Now what I don't get is, why does the old foreach loop not give the exception while the the new foreach loop does?

public void newForeachLoop() {
    for (Person person : list) {
        if (person.getPosition().equals(this.getPosition())) {
            list.remove(person);
        }
    }
}

public void oldForeachLoop() {
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).getPosition().equals(this.getPosition())) {
            list.remove(list.get(i));
        }
    }
}
11
  • Yes, both the loops serve the exact same purpose. Commented Aug 17, 2015 at 15:26
  • 3
    @Sky ... check this out stackoverflow.com/questions/9806421/… Commented Aug 17, 2015 at 15:26
  • 4
    oldForeachLoop doesn't use an iterator. No iterator, no problem with the list being modified. Commented Aug 17, 2015 at 15:28
  • @digidude I was trying to write something similar but you were the first:) Actually, I think you should make your comment an answer with some explanations Commented Aug 17, 2015 at 15:29
  • 2
    To clarify, there is only a single for-each loop in your code. the "oldForeachLoop" is just a simple for loop. Commented Aug 17, 2015 at 15:29

3 Answers 3

1

In the old loop you're not using the lists iterator instead you're using a count of the objects in the list.

In the new loop you're using the built-in iterator which is a pointer for that instance. When you remove an item from the list you're modifying that instance and resetting the iterator thus throwing the exception.

Sign up to request clarification or add additional context in comments.

6 Comments

So would you consider it bad practice to modify the list in the old loop?
Personally I wouldn't modify a list I was iterating through, I would copy the result to another list.
And how about cases where you don't need to keep iterating after you call remove? Is it okay to just call return; then? Or is it still better practice to just add it all to a list?
To make this answer complete, you can use the iterator to remove an element. See iterator interface doc. To do that, you can call the iterator method on the collection that implements iterable. You then use the iterator next method to traverse the collection with the option to call remove.
|
1

Because for each loop is iterator based, you can't just remove an element from the list while iterating over it. You can even try explicitly using iterator and removing an element.

    List<String> list= new ArrayList <String>;
    list.add("One");
    list.add("two");
    list.add("three");

    Iterator listItr = list.iterator () ;
    while ( listItr.hasNext() )
    {
      String countStr = itr.next();
      if ( countStr.equals ("two"))
          itr.remove(); //will not throw any exception

     //if you do it list.remove (countStr) //will throw exception 
    }  

Removing an element from list using index while iterating over it, will definitely not throw any exception but you need to be extra careful about its length getting modified. Even indexes of further elements are also disturbed by your operation. So if you take care of this its not a problem.

Comments

0

As @SacJn explained, you cannot make structural changes in the List (e.g. add or remove elements) while iterating it via iterator(). The iterator() will detect the inconsistency and throw a ConcurrentModificationException. In Java-8 there's clean and safe way to solve your task:

public void java8Solution() {
    list.removeIf(person -> person.getPosition().equals(this.getPosition()));
}

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.