Java - Remove items from List while iterating

This article introduces how to safely delete items during while iterating List.

While iterating the List using For Loop, if an item is deleted, an exception may occur or a problem may occur in which it is not possible to search for an item.

ConcurrentModificationException

If a specific item in ArrayList is deleted in the for loop as follows, ConcurrentModificationException may occur. When an item in the list is deleted during traversal, the Index of the next referenced item may be out of the range of the List, and an Exception occurs at this time.

The following code throws an Exception during traversal. This code has potential problems.

import java.util.ArrayList;
import java.util.List;

public class RemoveFromListIterating1 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("kiwi");
        list.add("melon");
        list.add("banana");

        for (String item : list) {
            if (item.equals("kiwi")) {
                list.remove(item);
            }
        }
    }
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
	at RemoveFromListIterating1.main(RemoveFromListIterating1.java:13)

Items missing during traversal

Even if ConcurrentModificationException does not occur, if an item is deleted while searching from a low index to a high index, some items may be excluded from the search.

If you run the code below, kiwi was not found during list traversal. Therefore, this code also has potential problems.

List<String> list = new ArrayList<>();
list.add("apple");
list.add("kiwi");
list.add("melon");
list.add("banana");

for (int i = 0; i < list.size(); i++) {
    String item = list.get(i);
    System.out.println("Iterating: " + item);
    if (item.equals("apple") || item.equals("kiwi")) {
        list.remove(item);
    }
}

System.out.println(list);

Output:

Iterating: apple
Iterating: melon
Iterating: banana
[kiwi, melon, banana]

1. Traversing the list from high index to low index

By traversing the list from high index to low index, you can safely delete items in a for loop. This is because deleting an item does not affect the Index of the next item to be searched for.

import java.util.ArrayList;
import java.util.List;

public class RemoveFromListIterating2 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("kiwi");
        list.add("melon");
        list.add("banana");

        for (int i = (list.size() - 1); i > -1; i--) {
            String item = list.get(i);
            System.out.println("Iterating: " + item);
            if (item.equals("kiwi")) {
                list.remove(item);
            }
        }

        System.out.println("Result: " + list);
    }
}

Output:

Iterating: banana
Iterating: melon
Iterating: kiwi
Iterating: apple
Result: [apple, melon, banana]

2. Search, then delete later

How to delete items using two for loops.

You can save the item to be deleted in the first Loop in another list and safely delete the item in the second Loop.

import java.util.ArrayList;
import java.util.List;

public class RemoveFromListIterating2_1 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("kiwi");
        list.add("melon");
        list.add("banana");

        List<String> removed = new ArrayList<>();
        for (String item : list) {
            System.out.println("Iterating: " + item);
            if (item.equals("kiwi")) {
                removed.add(item);
            }
        }

        for (String item : removed) {
            list.remove(item);
        }

        System.out.println("Result: " + list);
    }
}

Output:

Iterating: apple
Iterating: kiwi
Iterating: melon
Iterating: banana
Result: [apple, melon, banana]

3. Collection.removeIf()

Collection.removeIf() passes the functional interface Predicate as an argument, and safely deletes items that meet the condition.

import java.util.ArrayList;
import java.util.List;

public class RemoveFromListIterating3 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("kiwi");
        list.add("melon");
        list.add("banana");

        list.removeIf(item -> item.equals("kiwi"));

        System.out.println("Result: " + list);
    }
}

Output:

Result: [apple, melon, banana]

4. Iterator

An Iterator can be used to traverse a list and safely delete specific items.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RemoveFromListIterating4 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("kiwi");
        list.add("melon");
        list.add("banana");

        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String item = it.next();
            System.out.println("Iterating: " + item);
            if (item.equals("kiwi")) {
                it.remove();
            }
        }

        System.out.println("Result: " + list);
    }
}

Output:

Iterating: apple
Iterating: kiwi
Iterating: melon
Iterating: banana
Result: [apple, melon, banana]
codechachaCopyright ©2019 codechacha