Removing name if case matches from ArrayList not working

computerprogrammer :

I am trying to write a program that will remove names from an ArrayList if the name has specific value, but I am unable to do this.

class UserNamesTest {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("John");
        names.add("Jerry");
        names.add("Jim");
        names.add("Todd");

        for(String name : names) {
            if(name.equals("John")) {
                System.out.println("true");
                names.remove(names.indexOf(name));
            }
        }
    }
}

When I execute this code, I am getting an exception:

Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at UserNamesTest.main(UserNamesTest.java:13)

How can I accomplish this?

Jaeheon Shim :

The ConcurrentModificationException is thrown when something you are iterating on is modified. All general purpose implementations of Iterator that are provided by the JRE throw this exception. This exception is thrown because modifying a Collection while you are also iterating over it provides an undefined behavior or result of the iteration.

Note that just because the ConcurrentModificationException has the word "Concurrent" in it does not mean that it will happen only when another thread tries to modifiy the Collection. It can also happen in single thread implementations.

To fix this, you have two ways to go about the solution.

The first way would be able to retrieve the iterator manually from the Collection itself and use that to iterate:

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Jerry");
names.add("Jim");
names.add("Todd");

Iterator<String> namesIterator = names.iterator();
while(namesIterator.hasNext()) {
    String name = namesIterator.next();
    if(name.equals("John")) {
        System.out.println("true");
        namesIterator.remove();
    }
}

names.forEach(System.out::println);

As you can see, with this example the name John is removed from the ArrayList without throwing a ConcurrentModificationException. The other way to accomplish this would be to create a simple for loop, and access the elements using indices.

ArrayList<String> names = new ArrayList<>();
names.add("John");
names.add("Jerry");
names.add("Jim");
names.add("Todd");

for(int i = 0; i < names.size(); i++) {
    String name = names.get(i);
    if(name.equals("John")) {
        System.out.println("true");
        names.remove(i);
    }
}

names.forEach(System.out::println);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=334067&siteId=1