sam
sam

Reputation: 172

ConcurrentModificationException thrown on for each in android

i passing list of tags in forloop for iterate but its raised ConcurrentModificationException

 public void clearTag() {
    List<Tag> tags = binding.search.tagView.getTags();
    Log.d(TAG, "clearTags: " + tags);
    for (Tag tag : tags) {
        Log.d(TAG, "clearTag: " + tag + " " + tag.getLayoutColor());
        if (tag.getLayoutColor() == R.color.red) {
           tags.remove(tag);
        } else if (tag.getLayoutColor() == R.color.blue) {
            tags.remove(tag);
        } else if (tag.getLayoutColor() == R.color.green) {
            tags.remove(tag);
        }
    }
    updateTagVisibility();
    //resetFilter();
}

Upvotes: 3

Views: 342

Answers (3)

Swasti Gupta
Swasti Gupta

Reputation: 187

I recently encountered this exception. It occurs when you try to modify a collection you are already using/iterating.

Your for each loop picks one Tag object from the tags List and inside the loop you are removing the object from the same list. This is not allowed in Java.

You can alter your code like this :

public void clearTag(){
    List<Tag> tags = binding.search.tagView.getTags();
    // Create a dummy arrayList to store the tags to remove
    List<Tag> removedTags = new ArrayList<Tag>();
    Log.d(TAG, "clearTags: " + tags);
    for (Tag tag : tags) {
        Log.d(TAG, "clearTag: " + tag + " " + tag.getLayoutColor());
        if (tag.getLayoutColor() == R.color.red) {
           removedTags.add(tag);
        } else if (tag.getLayoutColor() == R.color.blue) {
            removedTags.add(tag);
        } else if (tag.getLayoutColor() == R.color.green) {
            removedTags.add(tag);
        }
    }

    // remove the tags
    tags.removeAll(removedTags)
    updateTagVisibility();
    //resetFilter();
}

Reference

Upvotes: 0

Crittje
Crittje

Reputation: 101

If you change your for each loop to a 'normal' for loop, like with (int = 0; i < size; i++), it possibly works. Make sure everytime you delete an element you have to go one element back i--;

Upvotes: 0

Yev Kanivets
Yev Kanivets

Reputation: 1800

This is because remove and add operations are not allowed while iterating through an array. So you need to store all elements to remove in different array, then remove them at once. Here is an example:

public void clearTag() {
    List<Tag> tags = binding.search.tagView.getTags();
    List<Tag> tagsToRemove = new ArrayList<>();
    Log.d(TAG, "clearTags: " + tags);
    for (Tag tag : tags) {
        Log.d(TAG, "clearTag: " + tag + " " + tag.getLayoutColor());
        if (tag.getLayoutColor() == R.color.red) {
           tagsToRemove.add(tag);
        } else if (tag.getLayoutColor() == R.color.blue) {
            tagsToRemove.add(tag);
        } else if (tag.getLayoutColor() == R.color.green) {
            tagsToRemove.add(tag);
        }
    }
    tags.removeAll(tagsToRemove);
    updateTagVisibility();
    //resetFilter();
}

Upvotes: 2

Related Questions