In this article, we are going to see 3 ways to remove an element from ArrayList in Java that matches a certain condition.
1. Remove Element from ArrayList using Iterator
Java Iterator allows us to iterate and remove every individual element within an ArrayList or 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 you use, 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
adjusts the pointer to the next element. As such,LinkedList.Iterator
performs much better thanArrayList.Iterator
when removing items.
package com.kodehelp.java8;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class RemoveElementFromList {
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 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.kodehelp.java8;
import java.util.ArrayList;
import java.util.List;
public class RemoveElementFromList {
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 ArrayList 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.kodehelp.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.