Remove Elements from Java Collections

In this article we are going to see different ways to remove elements from Java Collections which match certain condition.

1. Remove Elements from Java Collections using Iterator

Java Iterator allows us to iterate and remove every individual element within a Collection.

  • Depending on the collection that is used, you might run into ConcurrentModificationException exception.
  • You will need to iterate over the elements before you can remove them.
  • Depending on the collection that is used, remove may behave differently than expected. E.g.: ArrayList.Iterator removes the element from the collection and shifts subsequent data to the left whereas, LinkedList.Iterator simply adjusts the pointer to the next element. As such, LinkedList.Iterator performs much better than ArrayList.Iterator when removing items
package com.codehelp.java8;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RemoveElementFromList1 {
    public static void main(String[] args) {

        final List languages = new ArrayList<>();
        languages.add("Java");
        languages.add("Kotlin");
        languages.add("Python");
        languages.add("Scala");
        languages.add("Swift");

        System.out.println("Before Removing the elements: "+languages);
        
        final Iterator iterator = languages.iterator();
        while (iterator.hasNext()) {
            String lang = iterator.next();
            if(lang.startsWith("S")){
                iterator.remove();
            }
        }
        
        System.out.println("After Removing the elements: "+ languages);
    }
}

2. Remove Elements from Java Collections using Collection.removeIf()

Java 8 introduced a new method to the Collection interface that provides a more concise way to remove elements using Predicate:

languages.removeIf(lang -> lang.startsWith("S"));

It’s important to note that contrary to the Iterator approach, removeIf performs similarly well in both LinkedList and ArrayList.

In Java 8, ArrayList overrides the default implementation, which relies on Iterator, and implements a different strategy: first, it iterates over the elements and marks the ones that match our Predicate; afterward, it iterates a second time to remove (and shift) the elements that were marked in the first iteration.

package com.codehelp.java8;

import java.util.ArrayList;
import java.util.List;

public class RemoveElementFromList2 {
    public static void main(String[] args) {
        final List languages = new ArrayList<>();
        languages.add("Java");
        languages.add("Kotlin");
        languages.add("Python");
        languages.add("Scala");
        languages.add("Swift");

        System.out.println("Before Removing the elements: "+languages);
        
        languages.removeIf(lang -> lang.startsWith("S"));
        
        System.out.println("After Removing the elements: "+ languages);
    }
    
}

 

3. Remove Elements from Java Collections using Stream and Filter

Filtering elements using Stream is quite straightforward, we just need to create an instance of Stream using our Collection, invoke filter with our Predicate and then collect the result with the help of Collectors:

package com.codehelp.java8;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ListFilterInJava {
    public static void main(String[] args) {
        
        final List languages = Arrays.asList("Java", "Kotlin", "Python", "Scala", "Swift");

        // filter out the languages starting with S letter
        final List filteredLanguages = languages.stream()                           // convert list to stream
                                     .filter(lang -> lang!=null && !lang.startsWith("S"))   // filter out language starting with S
                                     .collect(Collectors.toList());                         // collect the output and convert streams to a List

        for (final String lang : filteredLanguages) {
            System.out.println(lang);    //output: Java, Kotlin, Python
        }
        
    }
}

Stream is less invasive than the previous approaches, it promotes isolation and enables the creation of multiple copies from the same source. However, we should keep in mind that it also increases the memory used by our application.

 

Also see :

Filter a List with Stream

Please Post Your Comments & Reviews

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.