2017-01-24 12 views
3

もちろん、私はこのエラーの意味を知っていますが、これを削除する方法はわかりません。 今すぐ試用していますカスタムArrayListを持つjava.util.ConcurrentModificationException

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

これは動作しません。 これは私のGLOBALLIST

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

である私はあまりにも反復処理しようとしているが、それはうまくいきませんでしたか、私は悪い何かをしました。

また、私はここでそれを使用する必要があります:私は、私はそのユーザーが表示されますが、EditTextでテキストを入力するときのように動作します。私は "アンドリュー"のような検索し、 "youko"私はエラーを取得します。

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

あらゆる種類のヘルプが関連付けられています。良い一日を! :)

編集 このケースでエラーが発生しました。

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

と私が持っているログに:

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

リストを反復しながら変更するときは、イテレータを使用する必要があります。 – jitinsharma

+0

** real ** [mcve]に一致するスタックトレースを提供してください。あるリストを反復するとき、別のリストから要素を削除するだけでうまくいくはずです。だから私は、あなたのコードは真実の部分だけを示していると仮定します。そして、記録のために:あなたはFriendsクラスの** override ** equalsをしましたか? – GhostCat

+0

@jitinsharma彼は**反復中に**リストを変更していない**です。彼はそのリストの**コピー**を操作しています! – GhostCat

答えて

2

これは不審な音:

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

あなたは反復がArrayListで許可されていないながら、自分自身にglobalSearchFriendsのコンテンツを追加してみてくださいしたがって、ConcurrentModificationExceptionにつながります。実際ArrayList#iterator()があることを意味fail-fast iterator返します。リストは構造イテレータ後の任意の時点を修正する

場合反復子自体removeまたはadd 方法以外の方法で、を 作成され、イテレータはConcurrentModificationExceptionを投げます。

それは通常/期待される動作のような音はありませんが、あなたは本当に単に代わりとして、次の反復のaddAll(Collection<? extends E> c)を使用し、リストの内容を複製するワンド場合:

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

NB:アンArrayListはスレッドセーフではないので、一覧にあるaddAll(Collection<? extends E> c)を確実に呼び出すことができます。リストが共有されていない場合、または明示的または内在的なロックの保護の下にある場合にのみ、予測できない動作が発生します。

+0

AddAllは動作することは保証されていません: "指定されたコレクションがこのリストであり、このリストが空でない場合、この呼び出しの動作は未定義です。 – Joni

+0

@Joniもちろん 'ArrayList'はスレッドセーフではありませんが、ここでは同期化されたブロック内で実行されるので問題ありません –

+0

これは私を助けました。問題は、私がfindedFriedsの新しいリストを作成するときに今、問題を抱えているすべてのものに1つのリストを使用することです。ありがとう、私を助けてくれました:) – Rodriquez

0

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

出力 リスト= [0、1、2、3、4、5、6、7、8、9、0、200、400、600、800]

0

下に試し
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); 
    } 
    } 
関連する問題