Java向ArrayList添加唯一产品时触发ConcurrentModificationException求助
问题分析与解决方案
错误原因
- ConcurrentModificationException触发原因:使用增强for循环(底层依赖
Iterator)遍历ArrayList时,直接调用productListArray.add(product)修改集合结构,触发了Iterator的fail-fast机制——迭代过程中集合的结构被修改(添加/删除元素),就会抛出该异常。 - 逻辑错误:当前
addProduct方法中,遍历每个元素时只要当前元素不匹配ID或名称就执行添加操作,会导致同一个符合条件的产品被重复添加多次(遍历多少次不匹配的元素就加多少次)。 - 冗余且错误的Iterator实现:
ProductList作为容器类不需要实现Iterator接口,且当前hasNext()和next()方法存在递归调用(next()返回自身),会直接导致栈溢出错误。
修正后的代码
import java.util.ArrayList; import java.util.Iterator; public class ProductList { private ArrayList<Product> productListArray = new ArrayList<>(); /* 单例模式实现(优化为线程安全的双重检查锁) */ private static volatile ProductList productListSingleton; private ProductList() {} public static ProductList instance() { if (productListSingleton == null) { synchronized (ProductList.class) { if (productListSingleton == null) { productListSingleton = new ProductList(); } } } return productListSingleton; } /* 向列表中添加产品的方法 */ public void addProduct(Product product) { boolean idExists = false; boolean nameExists = false; // 先遍历完整个列表,检查ID和名称是否重复 for (Product existingProduct : productListArray) { if (existingProduct.getProductId() == product.getProductId()) { idExists = true; break; // ID唯一,找到后无需继续遍历 } if (existingProduct.getProductName().equals(product.getProductName())) { nameExists = true; } } // 根据检查结果执行对应操作 if (idExists) { System.out.println("该产品已存在于列表中"); } else if (nameExists) { System.out.println("请为产品选择其他名称"); } else { productListArray.add(product); System.out.println("产品添加成功"); } } /* 从产品列表中移除产品 */ public void remove(int productId) { Iterator<Product> iteratorList = productListArray.iterator(); while (iteratorList.hasNext()) { Product product = iteratorList.next(); if (product.getProductId() == productId) { iteratorList.remove(); System.out.println("产品移除成功"); return; // ID唯一,找到后直接退出 } } System.out.println("未找到对应ID的产品"); } /* 检索产品列表 */ public void retrieve() { if (productListArray.isEmpty()) { System.out.println("产品列表为空"); return; } for (Product product : productListArray) { System.out.println(product); } } }
关键优化点
- 避免遍历中修改集合:先完成整个列表的遍历,确认ID和名称都不重复后,再执行添加操作,彻底解决ConcurrentModificationException。
- 修正逻辑错误:通过标记变量记录ID和名称是否存在,遍历结束后统一判断,避免重复添加。
- 移除错误的Iterator实现:删除不必要的
Iterator接口实现及错误的递归方法,避免栈溢出风险。 - 单例线程安全优化:加入
synchronized双重检查锁和volatile关键字,解决懒汉单例在多线程环境下可能生成多个实例的问题。
内容的提问来源于stack exchange,提问作者Abshir M
相关产品推荐
相关产品推荐

