Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.util.ConcurrentModificationException with custom ArrayList

Of course i know what does this error mean, but i don't know how to remove this. Now i'm trying with

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

But this doesn't work. This is my globallist

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

I'm trying iterating too, but it didn't work or i did something bad.

Also i need to use it here: where i search for a friend in api, this is working like when i input text in EditText then in my adapter i see that user, but this work only for few members, always when i search like "andrew" and then i search "youko" i get the error.

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

Any kind of help associated, Have a nice day! :)

Edit I got error on this case.

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

And on log i have:

   at java.util.ArrayList$ArrayListIterator.next
like image 563
Rodriquez Avatar asked Oct 27 '25 05:10

Rodriquez


1 Answers

This sounds suspicious:

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

You try to add the content of globalSearchFriends to itself while iterating which is not allowed with an ArrayList thus it leads to a ConcurrentModificationException. Indeed ArrayList#iterator() returns a fail-fast iterator which means that:

If the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.

It doesn't sound like a normal/expected behavior but if you really wand to duplicate the content of the list simply use addAll(Collection<? extends E> c) instead of iterating as next:

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

NB: An ArrayList is not thread-safe so ensure to call addAll(Collection<? extends E> c) on the list if and only if the list is not shared or under the protection of an explicit or intrinsic lock otherwise you will get an unpredictable behavior.

like image 109
Nicolas Filotto Avatar answered Oct 28 '25 19:10

Nicolas Filotto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!