Many times it happens when you are iterating over an ArrayList and you want to remove items from this list based on some condition. For Example, there is a list of students and you want to remove those students whose result is “Fail”. Code for this requirement is as simple as below :
// studentList is a list of students
for(Student student : studentList) {
// check if result of student is "Fail"
if(student.getResult().equals("Fail")) {
// remove it from list
studentList.remove();
}
}
The above code seems a piece of cake but it is not that way. It will not work and throw a java.util.ConcurrentModificationException
. This exception is thrown when a Collection is modified while it is being iterated. In the above scenario, how would you remove students from a list. Is there no way for it ? There is a way, in fact, there are many ways. This post will guide you through all of those.
Method 1 : Using a copy of List
Create a new list initialized with the elements of the list to be iterated. Then iterate the original list and when an element needs to be deleted from the list, delete it from the copy made initially and NOT from the original list (which is being iterated) as below :
// studentList is a list of students
List copyList = new ArrayList(studentList);
for(Student student : studentList) {
// check if result of student is "Fail"
if(student.getResult().equals("Fail")) {
// remove it from copy of list
copyList.remove();
}
}
Method 2 : Using iterator
Iterate over the list using a java.util.Iterator
and if you want to remove any object from the list, remove it using iterator’s remove
method only.
// studentList is a list of students
Iterator iterator = studentList.iterator();
// loop over the list using iterator
while(iterator.hasNext()) {
Student student = iterator.next();
// check if result of student is "Fail"
if(student.getResult().equals("Fail")) {
// remove it using iterator
iterator.remove();
}
}
iterator()
method of an ArrayList returns an instance of java.util.Iterator
which can be used to loop over the items of the list. Its hasNext()
method returns true if there are more elements to iterate in the list and its next()
method returns the next element in iteration. An element from the list can be safely removed by using iterator’s remove()
method. This method will remove the last element returned by iterator’s next()
method.
Method 3 : Using ListIterator
This method is similar to above method except that it uses java.util.ListIterator
in place of java.util.Iterator
. A ListIterator can be retrieved by using listIterator()
method of java.util.ArrayList
class as :
// studentList is a list of students
ListIterator listIterator = studentList.listIterator();
// loop over the list using iterator
while(listIterator.hasNext()) {
Student student = iterator.next();
// check if result of student is "Fail"
if(student.getResult().equals("Fail")) {
// remove it using iterator
listIterator.remove();
}
}
A ListIterator also has same methods as an Iterator. Its remove()
method also removes an element returned by next()
method.
Method 4 : Using new method added in Java 8
Java 8 has introduced a new method by which all elements matching a certain condition can be removed from the list in one go. There is no need of iterating over the list and using any of the methods explained above.
Java 8 release has added a new method removeIf()
in java.util.Collection
interface which takes a java.util.Predicate
as an argument. In simple words, it takes a condition on which you want to remove elements from the list. This condition will be tested on all elements of the list and those elements for which this condition returns true
will be removed from the list. An example will make it more clear.
// studentList is a list of students
studentList.removeIf(s -> s.getResult().equals("Fail"));
The expression s -> s.getResult().equals("Fail")
is a Lambda expression which returns true
for elements whose result field is “Fail”. The letter ‘s’ is just a variable and any sequence of characters can be used in place of it. It is just like a variable used as a counter in loop.
This method is the most easiest and compact method. But it can only be used if you are using Java 8.
Let’s tweak in :
java.util.ArrayList
has an overloaded constructor which takes another collection as argument. ArrayList is initialized to the contents of the collection passed in the constructor.remove()
method ofjava.util.Iterator
removes the last element returned by a call to itsnext()
method.java.lang.IllegalStateException
is thrown if you call iterator’sremove()
method before callingnext()
. This is an unchecked exception.java.util.ListIterator
has methods to traverse a list in reverse direction unlike thejava.util.Iterator
.removeIf()
method returnstrue
if any elements were removed from the list else returnsfalse
.removeIf()
method is adefault
method injava.util.Collection
interface. Methods withdefault
access modifier in an interface have an implementation.
Revert for any sort of feedback, comments and suggestions. Keep visiting and coding !!!