Подтвердить что ты не робот

Java.util.ConcurrentModificationException android после удаления элементов из списка массивов

У меня есть следующий код в приложении для Android:

/**
 * 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);

}

Этот метод вызывается в результате задачи async. Мне нужно удалить некоторые элементы коллекции, прежде чем перейти к адаптеру списка.

    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)
4b9b3361

Ответ 1

Вы не можете удалять элементы из списка, итерации по нему. Вам нужно использовать итератор и его метод удаления:

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

Ответ 2

Обычно вы получаете эту ошибку, когда

  • Вы изменяете коллекцию непосредственно во время итерации по коллекции

    или еще хуже, если

  • один поток изменяет коллекцию, а другой выполняет итерацию по ней.

Ответ 3

Не уверен, что принятый ответ будет работать, так как внутри он будет пытаться снова изменить тот же список. Более чистый подход состоял бы в том, чтобы сохранить список "удаления" и продолжать добавлять элементы в этот список в цикле. Когда мы будем готовы с списком удаления, они могут быть удалены после цикла. Это должно работать во всех случаях, когда нам не нужен удаленный элемент, подлежащий повторной обработке. Если да, то существующий список удалений можно проверить на наличие этого элемента.

    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);