-->

ConcurrentModificationException at for each androi

2019-08-30 04:05发布

问题:

I am passing Arraylist of ParseObject, and then i am putting one one foreach loop to extract the items with a condition when user object is not equals to null. There are two problems which i am facing. 1. If i am doing the following lines of code by passing different data to another list and then pass that list in my adapter, i am getting random data with numbers for example: If on item # 1 the name is "MAC" then it is showing in item 3.

ArrayList<ParseObject> checkRequestedNetArrayList = new ArrayList<ParseObject>();
requestedNetArrayList = (ArrayList<ParseObject>) objects;
MyResponsibilitesActivity.requestedNetArrayList = requestedNetArrayList;
adapterRequest = new GenericAdapter<ParseObject>(
    getApplicationContext(),
    requestedNetArrayList,
    R.layout.requested_trust_net_list_item,
    requestedDataBinder);

requestListView.setAdapter(adapterRequest);

requestedNetArrayList = (ArrayList<ParseObject>) objects;

for(ParseObject object: objects){
    System.out.println(object);
    object.getParseObject("user");
    if(object.has("user")){

        checkRequestedNetArrayList.add(object);

    }else{
        checkRequestedNetArrayList.remove(object);
    }

}

adapterRequest = new GenericAdapter<ParseObject>(
    getApplicationContext(),
    checkRequestedNetArrayList,
    R.layout.requested_trust_net_list_item,
requestedDataBinder);

requestListView.setAdapter(adapterRequest);
  1. If i am doing the following line of code to just direct giving the items in the same list, i am getting the java.util.ConcurrentModificationException

    for(ParseObject object: objects){
    
        if(object.has("user")){
    
            requestedNetArrayList.add(object);
    
        }
    }
    else{
        requestedNetArrayList.remove(object);
    }
    
    adapterRequest = new GenericAdapter<ParseObject>(
        getApplicationContext(),
        requestedNetArrayList,
        R.layout.requested_trust_net_list_item,
        requestedDataBinder);
    
    requestListView.setAdapter(adapterRequest);
    

    }

Please help me out here.

回答1:

You can not remove an element from list while accessing it. You have to use Iterator.

Where ever you are removing the object, use it.remove();

Iterator<ParseObject> it = objects.iterator();
while(it.hasNext()){
    Object object = it.next();
    //your stuff
    it.remove();
}

I think you might want to check this article about deep copy also.

UPDATE

Since you want to add elements to the list it is not directly possible with iterator. Now you are facing problem because you are directly assigning objects to requestedNetArrayList instead of that do it in the following way :

    ArrayList<ParseObject> requestedNetArrayList = new ArrayList<>(objects);

Then iterate over objects as you are doing now, and remove from or add to requestedNetArrayList (which you are pretty much already doing).



回答2:

When you make iteration using for-each construction for Collection

for (Object x : collection) ...

you have implicit creation of Iterator object for that Collection. This iterator performs a check: is collection was changed since iterator was created? If so, throwing an exception. So, you should avoid to any modify to your collection, until iterator done. That means, you should not use add and remove.

In either way, it is better to access ArrayList by index, because it will prevent creation of Iterator object. Like this:

for (int i = objects.size() - 1; i >= 0; i--) {
    ParseObject object = objects.get(i);
    // when iterating from tail to head, you can safely add or remove objects to/from this array list
}


回答3:

Instead of assigning the reference of objects to requestedNetArrayList, create a new ArrayList with the same contents

requestedNetArrayList=new ArrayList<ParseObject>(objects);

Then you can iterate on objects and modify requestedNetArrayList.