2012-11-23 12 views
12

Ho il codice folloing nella mia app Android:java.util.ConcurrentModificationException Android dopo rimuovere elementi dalla lista di array

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

} 

Questo metodo viene chiamato sul risultato di un compito asincrona. Devo rimuovere alcuni elementi della raccolta prima di passare alla scheda di elenco.

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) 

risposta

34

Non è possibile rimuovere elementi da un elenco durante l'iterazione su di esso. È necessario utilizzare un iteratore e il suo metodo di rimozione:

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

Grande. Funziona!. – brpaz

0

Si ottiene questo errore in genere quando

  1. È modificare direttamente la raccolta mentre è scorrere il collezione

    o addirittura peggio quando

  2. un thread modifica la raccolta, mentre un'altra itera su di essa.

+1

Otterrebbe quell'eccezione anche con un thread (in realtà probabilmente sta solo eseguendo un thread). – assylias

+0

Sì, anche l'iterazione e la modifica corrette. – AlexWien

0

Non so se la risposta accettata funzionerebbe, poiché internamente proverebbe a modificare di nuovo la stessa lista. Un approccio più pulito sarebbe quello di mantenere un elenco di "cancellazione" e continuare ad aggiungere elementi a tale elenco all'interno del ciclo. Una volta che siamo pronti con l'elenco di cancellazione, possono essere rimossi dopo il ciclo. Questo dovrebbe funzionare in tutti i casi in cui non è necessario rielaborare l'elemento eliminato. Se sì, allora la lista di cancellazione esistente può essere controllata per la presenza di quell'elemento.

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