我有2个列表suggestedFriends
和allSuggestedFriends
。
我使用迭代器来运行第一个列表并从此列表中删除项目。在途中,如果项目中仍有项目,则应从第二个列表中删除项目。我使用第二个迭代器(在SafeRemove方法中)只是为了从第二个列表中删除项目。
问题:有时我在行if (allSuggestedFriends.size() > 0) {
中得到一个ConcurrentModificationException,即使我使用迭代器来建议删除项目。
我应该使用迭代器来询问大小吗?我认为不可能(?!)
synchronized (suggestedFriends) {
for (final Iterator<User> suggestedFriendsIterator = suggestedFriends.iterator(); suggestedFriendsIterator.hasNext();) {
User friend = suggestedFriendsIterator.next();
if (friend.userId == request.getUserId()) {
final int index = suggestedFriends.indexOf(friend);
if (status) {
((FragmentActivityExt) context).runOnUiThread(new Runnable() {
@Override
public void run() {
if(suggestedFriends.size() > 0) {
suggestedFriendsIterator.remove();
}
notifyDataSetChanged();
if (allSuggestedFriends.size() > 0) {
suggestedFriends.add(2, allSuggestedFriends.get(0));
SafeRemove(allSuggestedFriends, allSuggestedFriends.get(0));
notifyDataSetChanged();
}
if (suggestedFriends.size() == 1) {
// FIXME workaround to fix list height as wrap_content is not supported by RecyclerView at the moment
//set to fit 1 element
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mListView.getLayoutParams();
params.height = EndoUtility.dpToPx(context, 70);
mListView.setLayoutParams(params);
}
if (suggestedFriends.size() == 0) {
EventBus.getDefault().post(new NoMoreSuggestedFriendsEvent());
}
}
});
} else {
if (mListView != null) {
((FragmentActivityExt) context).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, R.string.networkProblemToast, Toast.LENGTH_LONG).show();
((SuggestedFriendView) mListView.getChildAt(index)).reset();
}
});
}
}
break;
}
}
}
使用第二个迭代器的SafeRemove方法:
private void SafeRemove(List<User> list, User friend) {
Iterator<User> iter = list.iterator();
while (iter.hasNext()) {
User user = iter.next();
if (user.userId == friend.userId)
iter.remove();
}
}
更新
在synchronized
行周围添加SafeRemove(allSuggestedFriends, allSuggestedFriends.get(0));
会有解决方案吗?那样:
...
synchronized (allSuggestedFriends) {
SafeRemove(allSuggestedFriends, allSuggestedFriends.get(0));
}
...
或者更好的是,在SafeRemove方法中?像那样:
private void SafeRemove(List<User> list, User friend) {
synchronized (list) {
Iterator<User> iter = list.iterator();
while (iter.hasNext()) {
User user = iter.next();
if (user.userId == friend.userId)
iter.remove();
}
}
}
答案 0 :(得分:0)
好吧,由于我的问题被标记为可能重复,我没有得到任何答案。这是不幸的,因为我非常肯定讨论中的案例与建议的链接不同。
尽管如此,我没有使用allSuggestedFriends.size()
实现的关键字(正如我自己在我的更新中所建议的那样),但只是实现了一个并行计数器,当列表完成加载时,它与列表大小相符,并且然后在从列表中删除项目时递减。这消除了发生ConcurrentModificationException
的{{1}}检查。
...
private int allSuggestedFriendsCount;
...
// allSuggestedFriends loads items
...
allSuggestedFriendsCount = allSuggestedFriends.size();
...
...
if (allSuggestedFriendsCount > 0) {
suggestedFriends.add(2, allSuggestedFriends.get(0));
SafeRemove(allSuggestedFriends, allSuggestedFriends.get(0));
notifyDataSetChanged();
}
...
private void SafeRemove(List<User> list, User friend) {
Iterator<User> iter = list.iterator();
while (iter.hasNext()) {
User user = iter.next();
if (user.userId == friend.userId) {
iter.remove();
allSuggestedFriendsCount--;
}
}
}