java.util.ConcurrentModificationException android after remove elements from array list

20,785

Solution 1

You can't remove items from a list while iterating over it. You need to use an iterator and its remove method:

for(Iterator<Shop> it = result.iterator(); it.hasNext();) {
    Shop s = it.next();
    if(s.getClientPoints().getPointsSpent() == 0) {
        it.remove();
    }   
}

Solution 2

You get this error typically when

  1. You modify the collection directly while it is iterating over the collection

    or even worse when

  2. one threads modifies the collection, while another iterates over it.

Solution 3

Not sure if the accepted answer would work, as internally it would be trying to again modify the same list. A cleaner approach would be to maintain a 'deletion' list, and keep adding elements to that list within the loop. Once we are ready with the deletion list, they can be removed after the loop. This should work in all cases where we do not need the deleted element to be reprocessed. If yes, then the existing deletion list can be checked for presence of that element.

    List<String> list = new ArrayList<String>();
    List<String> listRemove = new ArrayList<String>();

    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    list.add("5");
    list.add("6");
    list.add("7");
    list.add("8");

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

    for (String i : list) {
        if (i.equals("2")) {
            listRemove.add(i);
        }
    }
    list.removeAll(listRemove);
    System.out.println("updated list: " + list);
Share:
20,785
brpaz
Author by

brpaz

Web Engineer, specialized in PHP/Symfony and Golang. Enthusiast about CI/CD, Code Quality and Engineering practices. Believer that Tech only makes sense at the service of people!

Updated on July 09, 2022

Comments

  • brpaz
    brpaz over 1 year

    I have the folloing code in my android app:

    /**
     * callback executed after fetching the data.
     */
    public void OnPointsFetch(ArrayList<Shop> result) {
    
        toggleLoader(false);
    
        this.shops = result;
    
        if(activeFilter == Constants.POINTS_FILTER_AVAILABLE){
            for(Shop s : result){
                if(s.getClientPoints().getPointsAvailable() == 0){
                    this.shops.remove(s);
                }
            }
        }
        else{
            for(Shop s : result){
                if(s.getClientPoints().getPointsSpent() == 0){
                    this.shops.remove(s);
                }   
            }
        }
    
    
        ptsListAdapter.setCollection(this.shops);
        ptsListAdapter.setFilter(this.activeFilter);
    
    }
    

    This method is called on the result of an async task. I need to remove some elements of the collection before passing to the list adapter.

        11-23 17:39:59.760: E/AndroidRuntime(19777): java.util.ConcurrentModificationException
    11-23 17:39:59.760: E/AndroidRuntime(19777):    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
    
  • assylias
    assylias over 11 years
    He would get that exception with one thread too (he is actually probably only running one thread).
  • Stony
    Stony over 5 years
    No, it can reduce the possibility. ArrayList is not thread-safe. If multiple thread modify the the same arrayList, the issue will also happen.