Ways of iterating
ConcurrentModificationException
.
Options for removing an item from a collection include:
Collection.removeIf
Iterator.remove
ListIterator.remove
(for List
s only; ListIterator
can both add and remove items)
Example
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.stream.Stream; /** Conditionally remove items from a Collection. */ public final class RemoveFromCollection { /** With Java 8, this is usually the preferred method. If the predicate is long, use a method reference expression instead of a lambda expression. @since Java 8 */ void withRemoveIf(){ Collection<String> words = words(); words.removeIf(w -> w.length() > MAX_WORD_LENGTH); } /** @since Java 1.2. */ void withIterator(){ Collection<Integer> numbers = numbers(); Iterator<Integer> iter = numbers.iterator(); while (iter.hasNext()){ Integer number = iter.next(); if (number > MAX_NUM){ iter.remove(); } } } /** In Effective Java, author Joshua Bloch advocates for this style of using Iterators. The benefit is that the scope of the iterator object is strictly confined to the loop in which it's used. @since Java 1.2 */ void withIteratorBlochianStyle(){ List<String> words = words(); for(Iterator<String> iter = words.iterator(); iter.hasNext();){ String word = iter.next(); if (word.length() > MAX_WORD_LENGTH){ iter.remove(); } } } /** ListIterator works with Lists only. @since Java 1.2 */ void withListIterator(){ List<String> words = words(); ListIterator<String> iter = words.listIterator(); while (iter.hasNext()){ String word = iter.next(); if (word.length() > MAX_WORD_LENGTH){ iter.remove(); } } } /** Always fails!. */ void withForEach(){ Collection<Integer> numbers = numbers(); for(Integer number : numbers){ //fails: ConcurrentModificationException if (number > MAX_NUM){ numbers.remove(number); } } } private List<String> words(){ return collectWords("Monty", "Python's", "Flying", "Circus"); } /** @since Java 8 */ private List<String> collectWords(String... words){ return Stream.of(words).collect(toList()); } private Collection<Integer> numbers(){ return collectNumbers(1,2,3,4,5); } /** @since Java 8 */ private Collection<Integer> collectNumbers(Integer... numbers){ return Stream.of(numbers).collect(toSet()); } private static final int MAX_WORD_LENGTH = 5; private static final int MAX_NUM = 3; /** Informal test. */ public static void main(String... args) { RemoveFromCollection remove = new RemoveFromCollection(); remove.withRemoveIf(); remove.withIterator(); remove.withIteratorBlochianStyle(); remove.withListIterator(); remove.withForEach(); } }