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 super E> filter)
This is a default method and is newly added in Collection interface in java 8.
[the_ad id=”644″]
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
[the_ad id=”656″]
Let’s tweak in :
removeIfmethod defined injava.util.Collectioninterface iterates over the collection using ajava.util.Iteratorand usesremove()method of iterator.removeIfmethod will remove all items matching the criteria in one go.removeIfmethod throws ajava.lang.NullPointerExceptionifnullis passed to it.- 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.
hasNext()method of java.util.Iterator returns true if there are more elements in the collection being iterated.next()method returns the next element of the collection being iterated. It throws ajava.util.NoSuchElementExceptionif there are no more elements in the collection. Hence the presence of an element should always be checked usinghasNext()method before callingnext().remove()method ofjava.util.Iteratorremoves the element returned by a call tonext()method.remove()method ofjava.util.Iteratorthrows ajava.lang.IllegalStateExceptionif it is called before callingnext()or it is called twice in succession.- Default implementation of
remove()method injava.util.Iteratorinterface throws ajava.lang.UnsupportedOperationException.
Hope this post let you learn something new. If it is, do share this post to let others also learn a bit.