Removing items from a list

When navigating through a list, I would like to remove the list item depending on the condition. See 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 I do that?

+69
java collections
Jun 24 '13 at 15:40
source share
6 answers

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

+54
Jun 24 '13 at 15:42
source share
 for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) { String a = iter.next(); if (...) { iter.remove(); } } 

Making an additional assumption that the list has strings. As already mentioned, list.iterator() is required. listIterator can do a bit of navigation.

+141
Jun 24 '13 at 15:44
source share

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

To avoid this situation, use Iterator, which ensures that you remove the item from the list safely ...

 List<Object> objs; Iterator<Object> i = objs.iterator(); while (i.hasNext()) { Object o = i.next(); //some condition i.remove(); } 
+21
Jun 24 '13 at 15:43
source share

You cannot and should not modify the list while iterating over it. You can solve this problem by temporarily saving objects for deletion:

 List<Object> toRemove = new ArrayList<Object>(); for(Object a: list){ if(a.getXXX().equalsIgnoreCase("AAA")){ toRemove.add(a); } } list.removeAll(toRemove); 
+11
Jun 24 '13 at 15:43
source share

Besides the excellent solutions offered here, I would like to propose another solution.

I'm not sure you can add dependencies, but if you can, you can add https://code.google.com/p/guava-libraries/ as a dependency. This library adds support for many basic functional operations in Java and can make it easier to work and work with collections.

In the code, I replaced the List type with T, since I don’t know what your list is printed on.

This problem can be solved with guava as follows:

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

And somewhere else you 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 too large in your situation. This is what becomes more powerful the more you work with collections.

Ohw, you also need these static imports:

 import static com.google.common.base.Predicates.not; import static com.google.common.collect.Collections2.filter; 
+5
Jun 24 '13 at 16:09
source share
 //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); 
+3
Jun 24 '13 at 15:42
source share



All Articles