Alex
Alex

Reputation: 23

ConcurrentModificationException in ArrayList<Object>

I understand that this exception is occurring because I'm trying to modify a list while I'm iterating through a list, but I don't understand how to get around it.

    for(Villager e : tasked)
    {
        if(!e.hasTask())
        {
            tasked.remove(e);
        }
    }

The code is pretty self-explanatory. If the villager "e" does not have a task, it should be removed from this list.

Upvotes: 1

Views: 108

Answers (4)

enterbios
enterbios

Reputation: 1755

If you are using java8 you can filter the list using stream API instead of iterating over it by hand.

List<Villager> villagersWithTask = tasked.stream().filter(e -> e.hasTask()).collect(Collectors.toList());

Upvotes: 0

M-Zaiady
M-Zaiady

Reputation: 176

Create separate list (e.g. itemsToRemove), that contains all items you want to remove and then use tasked.removeAll(itemsToRemoveList)

e.g.

   List<Villager> toRemove = new ArrayList();
for(Villager e : tasked)
{
    if(!e.hasTask())
    {
        toRemove.add(e);
    }
}
tasked.removeAll(toRemove);

The Only issue with this approach, if the 'toRemove' list size is very large, you can do the opposite 'ls.retainAll(c)', by only identify what you want to keep.

Upvotes: 0

Shoaib Chikate
Shoaib Chikate

Reputation: 8973

The ConcurrentModificationException is a RuntimeException that may be thrown by methods that have detected concurrent modification of an object, when such modification is not permissible. An example of not permissible behavior is when a thread tries to modify the internal structure of a Collection, while another thread is iterating over it.

Use Iterator's remove method.

 Iterator<Village> villageItr = tasked.iterator();
   while(villageItr.hasNext()){
     Village e=villageItr.next(); 
     if(!e.hasTask()){
            //remove that element from collection
            villageItr.remove();
        }

   }

Upvotes: 0

davek
davek

Reputation: 22925

Use a ListIterator, which allows you to make changes to the list through which you are iterating.

The code you use is almost indentical in use to an iterator, but removing elements has to be done explicitly using the remove() method of the iterator.

e.g.

    Iterator itr = tasked.iterator(); 
    while(itr.hasNext()) {
        Villager e = itr.next();
        if(!e.hasTask()) {
           itr.remove();
        }
    }

Upvotes: 1

Related Questions