4

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
10
  • 3
    You should use iterator when modifying a list while iterating it. Commented Jan 24, 2017 at 7:53
  • Please provide a real minimal reproducible example with a matching stack trace. When iterating one list, removing elements from another list should just work. So I assume that your code is only showing parts of the truth. And just for the record: you did override equals in your Friends class? Commented Jan 24, 2017 at 7:57
  • @jitinsharma He is not modifying the list while iterating. He is manipulating a copy of that list! Commented Jan 24, 2017 at 7:58
  • 1
    globalSearchFriends.clear(); removeFriendFromList(); The list is already empty, which you are iterating. Commented Jan 24, 2017 at 7:59
  • 1
    I told you. Please read about minimal reproducible example! And: the stack trace! Commented Jan 24, 2017 at 8:06

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

6 Comments

AddAll is not guaranteed to work: "the behavior of this call is undefined if the specified collection is this list, and this list is nonempty."
@Joni of course since ArrayList is not thread safe but here it is not the issue as it is done within a synchronized block
Yea this helped me. problem is that i use one list to everything, now when i create new list for findedFrieds im now have a problem with that. Thanks u helped me a lot :)
@Joni I added an NB for this
Read the documentation of the addAll method: Threads and locks have nothing to do with it. list.addAll(list) is not guaranteed to work, even though with the current implementation it does. (Maybe this is a documentation bug?)
|
0

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

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

Comments

0

Try below

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.