Android移除列表重复项遇ConcurrentModificationException的解决方法
修复Android列表去重时的ConcurrentModificationException错误
错误原因
你遇到的java.util.ConcurrentModificationException,是因为在使用forEach遍历dataListTemp集合时,直接调用集合的remove()方法修改了集合结构。forEach本质依赖迭代器实现,迭代过程中集合结构发生变化(添加/删除元素)会触发迭代器的并发修改校验,进而抛出异常。
修复方案
方案一:使用迭代器的remove方法
直接用集合的迭代器完成遍历和删除操作,迭代器的remove()方法会同步更新自身状态,不会触发并发修改异常:
if (ALLERGIC_LIST.isNotEmpty()) { ALLERGIC_LIST.forEach { allergic -> // 将元素添加到用户列表 userLocalList.add(LocalDataModel(allergic.faName.toString(), true, 0, allergic.id!!)) // 使用迭代器遍历并移除匹配项 val iterator = dataListTemp.iterator() while (iterator.hasNext()) { val temp = iterator.next() Log.e("AllergicLogs","${allergic.id} - ${temp.id}") if (allergic.id == temp.id) { iterator.remove() // 调用迭代器的remove方法 break // 找到匹配项后退出循环,无需继续遍历 } } } // 统一刷新适配器,避免循环内频繁刷新影响性能 userRecyclerView.adapter?.notifyDataSetChanged() searchList.adapter?.notifyDataSetChanged() }
方案二:Kotlin简洁写法(推荐)
通过收集需要移除的ID集合,一次性过滤并更新dataListTemp,代码更简洁且性能更优:
if (ALLERGIC_LIST.isNotEmpty()) { // 收集所有需要移除的过敏项ID val allergicIds = ALLERGIC_LIST.map { it.id!! }.toSet() // 批量添加到用户列表 userLocalList.addAll(ALLERGIC_LIST.map { LocalDataModel(it.faName.toString(), true, 0, it.id!!) }) // 过滤掉重复项,重新赋值给临时列表 dataListTemp = dataListTemp.filterNot { allergicIds.contains(it.id) }.toMutableList() // 统一刷新适配器 userRecyclerView.adapter?.notifyDataSetChanged() searchList.adapter?.notifyDataSetChanged() }
额外优化建议
- 避免在循环内频繁调用
notifyDataSetChanged():多次刷新RecyclerView会导致不必要的UI重绘,影响应用流畅度,建议在所有数据操作完成后统一调用一次。 - 替换
!!为安全调用?.:adapter!!可能引发空指针异常,改用adapter?.notifyDataSetChanged()可以在适配器为空时静默跳过,避免崩溃。
内容的提问来源于stack exchange,提问作者Dr.KeyOk
相关产品推荐
相关产品推荐

