You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迭代添加元素触发ConcurrentModificationException的问题求助

解决迭代集合时添加元素触发ConcurrentModificationException的问题

问题根源

你代码里的核心问题是遍历mUsers集合的同时调用mUsers.add(user):

for(User user1 : mUsers){
    if(!user.getId().equals(user1.getId())){
        mUsers.add(user);
    }
}

ArrayList的增强for循环依赖迭代器实现,而ArrayList的迭代器采用fail-fast机制——迭代过程中集合结构(添加/删除元素)被修改时,会直接抛出ConcurrentModificationException。另外这段逻辑本身存在错误:只要当前user与mUsers中任意一个user1的id不同就执行添加,会导致同一个user被重复加入多次。

解决方案

方案1:用HashSet维护已存在的用户ID(推荐,高效去重)

用HashSet存储已加入mUsers的用户ID,快速判断当前用户是否已存在,彻底避免遍历集合时修改结构的操作:

private void readChats(){
    mUsers = new ArrayList<>();
    // 用HashSet存储已存在的用户ID,O(1)时间复杂度判断是否重复
    Set<String> existingUserIds = new HashSet<>();

    reference = FirebaseDatabase.getInstance().getReference("Users");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            mUsers.clear();
            existingUserIds.clear();
            for(DataSnapshot dataSnapshot : snapshot.getChildren()){
                User user = dataSnapshot.getValue(User.class);

                // 检查当前用户ID是否在目标列表中,且未被加入过mUsers
                for(String id : usersList){
                    if(user.getId().equals(id) && !existingUserIds.contains(user.getId())){
                        mUsers.add(user);
                        existingUserIds.add(user.getId());
                        break; // 找到匹配ID后跳出循环,避免重复判断
                    }
                }
            }
            userAdapter = new UserAdapter(getContext(), mUsers, true);
            recyclerView.setAdapter(userAdapter);
        }

        // 必须实现的数据库读取失败回调
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 这里可以添加读取失败的提示或日志
        }
    });
}

方案2:使用迭代器判断存在性后添加

如果一定要基于原集合遍历判断,可以先通过迭代器确认元素是否存在,再执行添加操作(不会触发异常):

// 替换原代码中遍历mUsers的逻辑
if(mUsers.size() != 0){
    boolean userExists = false;
    Iterator<User> iterator = mUsers.iterator();
    while(iterator.hasNext()){
        User user1 = iterator.next();
        if(user.getId().equals(user1.getId())){
            userExists = true;
            break;
        }
    }
    if(!userExists){
        mUsers.add(user);
    }
}else{
    mUsers.add(user);
}

此方案需要遍历集合判断存在性,元素较多时效率低于HashSet方案。

额外优化建议

  • 若usersList是频繁查询的集合,可转为HashSet,将user.getId()的存在判断从O(n)降至O(1):
    Set<String> usersIdSet = new HashSet<>(usersList);
    // 后续直接用usersIdSet.contains(user.getId())判断
    

内容的提问来源于stack exchange,提问作者Abderrazzakk Belghite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 03:48:09