How to remove an item from a list matching some condition in java

Scenario

Suppose there is a list of objects. It may happen that you want to delete an object which satisfies a certain condition from it. Let’s say there is a Student class as below :

public class Student {
   private String name;
   private String grade;
   private String result;

   // getter and setter methods 
}

There is a list of Student objects where each object has the result field value either “Pass” or “Fail”. Requirement is to delete all Students whose result field is equal to Fail.

How ?

There are two ways to delete all items from a list matching some criteria.

Method 1 : Using Collection interface in java 8

Java 8 provides a new way to remove items from a collection such as a List or a Set based on whether those items match a given condition.

Let’s say we have a list of Student objects and we want to remove those students whose result field has a value “Fail”. We can do this using below code :

List students = new ArrayList();
Student passStudentOne = new Student();
passStudentOne.setResult("Pass");
Student passStudentTwo = new Student();
passStudentTwo.setResult("Pass");
Student failStudent = new Student();
failStudent.setResult("Fail");
list.add(passStudentOne);
list.add(passStudentTwo);
list.add(failStudent);
System.out.println("Number of total students : " + students.size());
students.removeIf(s -> s.getResult().equalsIgnoreCase("fail"));
System.out.println("Number of total students : " + students.size());

Output

Number of total students : 3
Number of total students : 2

The student matching the condition has been removed from the list.

Explanation

java.util.Collection has a method named as removeIf which takes a java.util.function.Predicate as argument. Thus the signature of the method is

boolean removeIf(Predicate filter)

This is a default method and is newly added in Collection interface in java 8.

java.util.Predicate is a Functional interface which means it has a single method(named test) which accepts a single argument and returns a boolean value. Thus, where a Predicate is required, we can pass a Lambda expression which has a single argument and returns a boolean result. In the above example, the Lambda expression is s ->s.getResult().equalsIgnoreCase("fail"). This expression takes one argument and returns either true or false.

Method 2 : Using java.util.Iterator

java.util.Iterator is used for iterating over a linear collection such as a List or a Set. It also has a remove() method which can be used to remove an item from the collection.

Taking the above example, while iterating over the list, we check the value of result field of student object. If it is “fail”, then remove the object from the list as below.

List students = new ArrayList();
Student passStudentOne = new Student();
passStudentOne.setResult("Pass");
Student passStudentTwo = new Student();
passStudentTwo.setResult("Pass");
Student failStudent = new Student();
failStudent.setResult("Fail");
list.add(passStudentOne);
list.add(passStudentTwo);
list.add(failStudent);
System.out.println("Number of total students : " + students.size());
Iterator iterator = students.iterator();
while(iterator.hasNext()) {
   Student student = iterator.next();
   if(student.getResult.equalsIgnoreCase("fail")) {
       iterator.remove();
   }
}
System.out.println("Number of total students : " + students.size());

Output

Number of total students : 3
Number of total students : 2

Let’s tweak in :

  1. removeIf method defined in java.util.Collection interface iterates over the collection using a java.util.Iterator and uses remove() method of iterator.
  2. removeIf method will remove all items matching the criteria in one go.
  3. removeIf method throws a java.lang.NullPointerException if null is passed to it.
  4. An iterator always progresses in front direction during its iteration. That is,  we can always get the next element of the collection. It can not be used to get previous element of the collection.
  5. hasNext() method of java.util.Iterator returns true if there are more elements in the collection being iterated.
  6. next() method returns the next element of the collection being iterated. It throws a java.util.NoSuchElementException if there are no more elements in the collection. Hence the presence of an element should always be checked using hasNext() method before calling next().
  7. remove() method of java.util.Iterator removes the element returned by a call to next() method.
  8. remove()method of java.util.Iterator throws a java.lang.IllegalStateException if it is called before calling next() or it is called twice in succession.
  9. Default implementation of remove() method in java.util.Iterator interface throws a java.lang.UnsupportedOperationException.

Hope this post let you learn something new. If it is, do share this post to let others also learn a bit.

Leave a Reply