Remove from a collection

Sometimes you need to conditionally remove an item from a collection. You can't do that in an enhanced-for loop, because it fails with a ConcurrentModificationException.

Options for removing an item from a collection include:

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();
  }
} 

See Also :
Ways of iterating