how to avoid concurrentModificationException when removing an object from to ArrayLists"

negar.n :

Consider the following code.

As you might expect, the deleteFruitByName method throws a ConcurrentModificationException when a fruit is removed inside a for-each loop.

How can i avoid that in such cases?

import java.util.ArrayList;

public class Stringplay {
    public static void main(String[] args) {
        ArrayList<Fruit> fruites = new ArrayList<Fruit>();
        new Fruit(32, "apple", "red");
        new Fruit(64, "orange", "orange");
        new Fruit(12, "banana", "red");
        new Fruit(42, "grape", "purple");
        fruites.addAll(Fruit.fruits);
        Fruit.deleteFruitByName("apple");
        for (Fruit fruit : fruites) {
            System.out.println(fruit.getName());
        }
    }

}

public class Fruit {
    public int weight;
    public String name;
    public String type;
    public static ArrayList<Fruit> fruits = new ArrayList<Fruit>();

    public Fruit(int weight, String name, String type) {
        this.weight = weight;
        this.name = name;
        this.type = type;
        fruits.add(this);
    }

    public String getName() {
        return name;
    }

    public static void deleteFruitByName(String fruitName) {
        for (Fruit fruit : fruits) {
            if (fruit.getName().equals(fruitName)) {
                fruits.remove(fruit);
            }
        }

    }
}


Boris Chistov :

To avoid ConcurrentModificationException you need to use Iterator here.

    public static void deleteFruitByName(String fruitName) {
        Iterator<Fruit> it = fruits.iterator();
        while (it.hasNext()) {
            Fruit fruit = it.next();
            if (fruit.getName().equals(fruitName)) {
                it.remove();
            }
        }
    }

From java doc

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Update: to iterate collection in class Fluit use this code

public class Main {

    public static void main(String[] args) {
        new Fruit(32, "apple", "red");
        new Fruit(64, "orange", "orange");
        new Fruit(12, "banana", "red");
        new Fruit(42, "grape", "purple");
        Fruit.deleteFruitByName("apple");
        for (Fruit fruit : Fruit.fruits) {
            System.out.println(fruit.getName());
        }
    }
}

Guess you like

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