Removing items from a list

JavaCollections

Java Problem Overview


While looping through a list, I would like to remove an item of a list depending on a condition. See the code below.

This gives me a ConcurrentModification exception.

for (Object a : list) {
	if (a.getXXX().equalsIgnoreCase("AAA")) {
		logger.info("this is AAA........should be removed from the list ");
		list.remove(a);
	}
}

How can this be done?

Java Solutions


Solution 1 - Java

for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
    String a = iter.next();
    if (...) {
        iter.remove();
    }
}

Making an additional assumption that the list is of strings. As already answered, an list.iterator() is needed. The listIterator can do a bit of navigation too.

ā€“---------

Update

As @AyushiJain commented, there is

list.removeIf(...);

Solution 2 - Java

You need to use Iterator and call remove() on iterator instead of using for loop.

Solution 3 - Java

You cannot do it because you are already looping on it.

Inorder to avoid this situation use Iterator,which guarentees you to remove the element from list safely ...

List<Object> objs;
Iterator<Object> i = objs.iterator();
while (i.hasNext()) {
   Object o = i.next();
  //some condition
    i.remove();
}

Solution 4 - Java

You can't and shouldn't modify a list while iterating over it. You can solve this by temporarely saving the objects to remove:

List<Object> toRemove = new ArrayList<Object>();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        toRemove.add(a);
    }
}
list.removeAll(toRemove);

Solution 5 - Java

Besides all the excellent solutions offered here I would like to offer a different solution.

I'm not sure if you're free to add dependencies, but if you can, you could add the https://code.google.com/p/guava-libraries/ as a dependency. This library adds support for many basic functional operations to Java and can make working with collections a lot easier and more readable.

In the code I replaced the type of the List by T, since I don't know what your list is typed to.

This problem can with guava be solved like this:

List<T> filteredList = new Arraylist<>(filter(list, not(XXX_EQUAL_TO_AAA)));

And somewhere else you then define XXX_EQUAL_TO_AAA as:

public static final Predicate<T> XXX_EQUAL_TO_AAA = new Predicate<T>() {
    @Override
    public boolean apply(T input) {
        return input.getXXX().equalsIgnoreCase("AAA");
    }
}

However, this is probably overkill in your situation. It's just something that becomes increasingly powerful the more you work with collections.

Ohw, also, you need these static imports:

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;

Solution 6 - Java

//first find out the removed ones

List removedList = new ArrayList();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        logger.info("this is AAA........should be removed from the list ");
        removedList.add(a);

    }
}

list.removeAll(removedList);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTechieView Question on Stackoverflow
Solution 1 - JavaJoop EggenView Answer on Stackoverflow
Solution 2 - JavakosaView Answer on Stackoverflow
Solution 3 - JavaSuresh AttaView Answer on Stackoverflow
Solution 4 - JavaAndré StannekView Answer on Stackoverflow
Solution 5 - JavaBart EnkelaarView Answer on Stackoverflow
Solution 6 - JavaMakkyView Answer on Stackoverflow