The Java List interface represents the ordered Collection allowing duplicate elements. The list provides various methods to add, remove or search for an element. You can remove an element efficiently in any of the objects of the List implementation classes like ArrayList, LinkedList, Stack and Vector.
You can use Java 8 Collection.removeIf(predicateFn())
method to find and remove all the elements that match the condition supplied using the predicate function(x -> x==null).
In this article, you will learn about different possibilities introduced in Java 8 to find and remove an element from a List.
Using RemoveIf() method
In Java 8, a new method(.removeIf()
) was introduced in the Collection interface to remove all the elements of the collection that satisfy the given predicate.
How it works
- The
.removeIf(predicateFn)
method expects a predicate function(x -> (x == null)
) as a parameter and removes all the elements of the collection that satisfies the condition. - The method will return true , if any elements were removed.
- If the specified function is null, then NullPointerException is thrown.
- If an element matches the condition and cannot be removed from the collection, then UnsupportedOperationException will be thrown. You have to use any of the List implemented classes as the object to avoid this exception.
Use this method to find and remove elements in the original object.
Code
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
//main
List<String> names = new ArrayList<>(Arrays.asList(null, "Alex", "Priya", null, "Jessica", "Ameer"));
System.out.println(names); //[null, Alex, Priya, null, Jessica, Ameer]
Predicate<String> predicate = x -> (x == null);
names.removeIf(value-> predicate.test(value));
System.out.println(names); //[Alex, Priya, Jessica, Ameer]
In the above example, the list.removeIf()
accepts a predicate function(x -> (x == null)), and as a result, all the null
values in the original object(names
) are removed.
To find and remove an element in an LinkedList object is demonstrated below,
LinkedList<Student> students = new LinkedList<>(Arrays.asList(new Student(null, 100)
,new Student("David", 101)
,new Student("Kumar", 102)
,new Student(null, 103)));
System.out.println(students); //[Student(name=null, id=100), Student(name=David, id=101), Student(name=Kumar, id=102), Student(name=null, id=103)]
Predicate<Student> predicate = x -> (x.getName() == null);
students.removeIf(predicate);
System.out.println(students); //[Student(name=David, id=101), Student(name=Kumar, id=102)]
Using Filter() method
The Java 8 Stream’s .filter()
method returns a stream consisting of elements that match the given condition or removing the elements that don’t match the condition.
To find and remove an element in a list using the .filter()
method,
- Iterate the stream and invoke
.filter()
with a predicate condition(x-> (x%2 == 0)
). - The predicate condition is applied to each stream element, and only the elements that satisfy the condition are returned.
- Convert the stream of elements into a new List using the
.toCollect()
method.
Use this method when an original object should not be affected.
Code
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
//main
List<Integer> numbers = Arrays.asList(1,3,5,7,2,4,6,8);
System.out.println(numbers); //[1, 3, 5, 7, 2, 4, 6, 8]
Predicate<Integer> predicate = x-> (x%2 == 0);
List evenNumbers = numbers.stream().filter(value -> predicate.test(value))
.collect(Collectors.toList());
System.out.println(evenNumbers); //[2, 4, 6, 8]
In the above example, the predicate condition(x-> (x%2 == 0)
) to find the elements that are divisible by two
is used to identify the even numbers and is returned a new List.
When invoked with predicate.negate()
, the predicate function produces the inverse results below, removing the even numbers and adding odd numbers as a new List.
Predicate<Integer> predicate = x-> (x%2 == 0);
List oddNumbers = numbers.stream().filter(value -> predicate.negate().test(value))
.collect(Collectors.toList());
System.out.println(oddNumbers); //[1, 3, 5, 7]
Using Stream ForEach Add/Remove to new List
The Java 8 Stream’s .forEach()
method uses the .filter()
method to identify the elements based on the condition and add/remove the elements into a new list.
To add elements to the new list using the forEach()
method,
- Iterate the
original list
and use.filter()
to get the elements based on the condition. - Use
.forEach
method to iterate on filtered elements and add each element to anew list
.
Use this method when you want both original data and filtered data.
Code
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
//main
List<Integer> numbers = Arrays.asList(1,3,5,7,2,4,6,8);
System.out.println(numbers); //[1, 3, 5, 7, 2, 4, 6, 8]
Predicate<Integer> predicate = x-> (x >5);
List<Integer> newList = new ArrayList<>();
numbers.stream().filter(value-> predicate.test(value)).forEach(newList::add);
System.out.println(newList); //[7, 6, 8]
To remove elements to the new list using the forEach()
method,
- Copy the
Original List
to another new List(copyList
). - Iterate the
copyList
and usefilter()
to get the elements satisfying the condition. - Use
forEach
to iterate over the filtered elements and remove elements of the original elements(numbers::remove
) matching the filtered elements. - Now, the elements will be removed from the original list.
Code
List<Integer> numbers = new ArrayList<>(Arrays.asList(1,3,5,7,2,4,6,8));
System.out.println(numbers); //[1, 3, 5, 7, 2, 4, 6, 8]
List<Integer> copyList = new ArrayList<>(numbers);
System.out.println(copyList); //[1, 3, 5, 7, 2, 4, 6, 8]
Predicate<Integer> predicate = x-> (x >5);
copyList.stream().filter(predicate::test).forEach(numbers::remove);
System.out.println(numbers); //[1, 3, 5, 2, 4]