2017-01-24 2 views
3

Natürlich weiß ich, was dieser Fehler bedeutet, aber ich weiß nicht, wie das zu entfernen ist. Jetzt versuche ich, mitjava.util.ConcurrentModificationException mit benutzerdefinierter ArrayList

private void removeFriendFromList() { 
    List<Friend> copy = new ArrayList<Friend>(globalSearchFriends); 
    for (Friend friend : globalSearchFriends) { 
     if (friend.equals(remove)) { 
      copy.remove(friend); 
     } 
    } 
} 

Aber das funktioniert nicht. Das ist mein globallist

private List<Friend> globalSearchFriends = new ArrayList<>(); 

ich Iterieren auch ich versucht, aber es hat nicht funktioniert oder ich habe etwas Schlimmes.

Auch ich muss es hier verwenden: wo ich suche nach einem Freund in api, das funktioniert wie wenn ich Text in EditText eingeben dann in meinem Adapter sehe ich diesen Benutzer, aber das funktioniert nur für wenige Mitglieder, immer wenn ich suche wie "andrew" und dann suche ich "youko" ich bekomme den fehler.

private void serachFriend(final String query) { 

    etGlobalSearch.addTextChangedListener(new TextWatcherAdapter() { 
     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      FindFriend request = new FindFriend(); 
      request.query = query; 
      request.query = s.toString().toLowerCase().trim(); 
      backend.findFriend(request).enqueue(new Callback<ResponseFindFriend>() { 
       @Override 
       public void onResponse(Call<ResponseFindFriend> call, Response<ResponseFindFriend> response) { 
        synchronized (globalSearchFriends) { 
         globalSearchFriends.clear(); 
         removeFriendFromList(); 
         try { 
          if (response == null) 
           throw new Exception(); 
          if (!response.isSuccessful()) 
           throw new Exception(); 
          if (response.body() == null) 
           throw new Exception(); 
          if (response.body().results == null) 
           throw new Exception(); 
          globalSearchFriends = response.body().results; 
         } catch (Exception e) { 
          Log.d("Blad", "sobie"); 
         } finally { 
          gatherResults(); 
         } 
        } 
       } 

       @Override 
       public void onFailure(Call<ResponseFindFriend> call, Throwable t) { 
        synchronized (globalSearchFriends) { 
         globalSearchFriends.clear(); 
         removeFriendFromList(); 
         gatherResults(); 
        } 
       } 
      }); 
     } 
    }); 
} 

private void removeFriendFromList() { 
    List<Friend> copy = new ArrayList<Friend>(globalSearchFriends); 
    for (Friend friend : globalSearchFriends) { 
     if (friend.equals(remove)) { 
      copy.remove(friend); 
     } 
    } 
} 

private void gatherResults() { 
    removeFriendFromList(); 
    for (Friend f : globalSearchFriends) 
     globalSearchFriends.add(f); 
    findedFriendsAdapter.setFriendList(globalSearchFriends); 
} 

Jede Art von Hilfe verbunden, Einen schönen Tag! :)

Bearbeiten Ich habe Fehler in diesem Fall.

java.util.ConcurrentModificationException 
    for (Friend f : globalSearchFriends) 
     globalSearchFriends.add(f); 
    findedFriendsAdapter.setFriendList(globalSearchFriends); 

Und auf log ich habe:

at java.util.ArrayList$ArrayListIterator.next 
+3

Sie sollten Iterator verwenden, wenn Sie eine Liste während der Iteration ändern. – jitinsharma

+0

Bitte geben Sie eine ** echte ** [mcve] mit einem passenden Stack-Trace an. Beim Iterieren einer Liste sollte das Entfernen von Elementen aus einer anderen Liste einfach funktionieren. Ich nehme also an, dass dein Code nur Teile der Wahrheit zeigt. Und nur für den Rekord: Du hast ** override ** equals in deiner Friends-Klasse? – GhostCat

+0

@jitinsharma Er ändert ** die Liste nicht während der Iteration. Er manipuliert eine ** Kopie ** dieser Liste! – GhostCat

Antwort

2

Diese verdächtig klingt:

for (Friend f : globalSearchFriends) 
    globalSearchFriends.add(f); 

Sie versuchen, den Inhalt von globalSearchFriends sich während Iterieren hinzuzufügen, die mit einem nicht erlaubt ist ArrayList also führt es zu einem ConcurrentModificationException. Tatsächlich ArrayList#iterator() gibt ein fail-fast iterator was bedeutet, dass:

Wenn die Liste strukturell jederzeit nach dem Iterator modifiziert wird erstellt, in irgendeiner Weise außer durch den eigenen remove oder add Methoden des Iterators, die Iterator wird ConcurrentModificationException werfen.

Es ist nicht wie ein normales/erwartetes Verhalten klingt, aber wenn Sie wirklich den Inhalt der Liste zu duplizieren Stab einfach addAll(Collection<? extends E> c) verwendet stattdessen als nächstes Laufen:

globalSearchFriends.addAll(globalSearchFriends); 
// or globalSearchFriends.addAll(new ArrayList<>(globalSearchFriends)); for safety 
findedFriendsAdapter.setFriendList(globalSearchFriends); 

NB: Eines ArrayList ist nicht threadsicher, also stellen Sie sicher, dass Sie addAll(Collection<? extends E> c) in der Liste aufrufen, wenn und nur wenn die Liste nicht geteilt wird oder unter dem Schutz einer expliziten oder intrinsischen Sperre, sonst erhalten Sie ein unvorhersehbares Verhalten.

+0

AddAll funktioniert nicht garantiert: "Das Verhalten dieses Aufrufs ist nicht definiert, wenn die angegebene Auflistung diese Liste ist und diese Liste nicht leer ist." – Joni

+0

@Joni natürlich, da 'ArrayList' nicht Thread-sicher ist, aber hier ist es nicht das Problem, wie es in einem synchronisierten Block getan wird –

+0

Ja, das hat mir geholfen. Problem ist, dass ich eine Liste zu allem verwende, jetzt, wenn ich neue Liste für findedFrieds erstelle, habe ich jetzt ein Problem damit. Danke, du hast mir sehr geholfen :) – Rodriquez

0

Wie wäre es mit CopyOnWrite Collection?

public static void main(String[] args) { 
    CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList(); 
    for (int i = 0; i < 10; i++) { 
     list.add(i); 
    } 

    for (Integer num : list) { 
     if (num % 2 == 0) { 
      list.add(num * 100); 
     } 
    } 
    System.out.println("list = " + list); 
} 

Ausgang list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 200, 400, 600, 800]

0

Versuchen unter

private void removeFriendFromList() { 
    List<Friend> copy = new ArrayList<Friend>(globalSearchFriends); 
    Friend targetToRemove = null; 
    for (Friend friend : globalSearchFriends) { 
     if (friend.equals(remove)) { 
     targetToRemove = friend; 
     } 
    } 
    if (targetToRemove != null) { 
     copy.remove(targetToRemove); 
    } 
    } 
Verwandte Themen