ConcurrentModificationException
是 Java 集合框架中常见的异常,通常发生在使用迭代器遍历集合时,集合的结构被修改(例如添加、删除元素),但未通过迭代器本身进行修改。为了避免该异常,可以采取以下方法:
1. 使用迭代器的 remove()
方法
- 在遍历集合时,如果需要删除元素,应该使用迭代器提供的
remove()
方法,而不是直接调用集合的remove()
方法。 - 示例:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if ("B".equals(item)) { iterator.remove(); // 使用迭代器的 remove() 方法 } }
2. 使用并发集合类
- 如果需要在多线程环境下修改集合,可以使用
java.util.concurrent
包中的并发集合类,如CopyOnWriteArrayList
、ConcurrentHashMap
等。 - 这些集合类在设计上支持并发修改,不会抛出
ConcurrentModificationException
。 - 示例:
List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("A", "B", "C")); for (String item : list) { if ("B".equals(item)) { list.remove(item); // 安全操作 } }
3. 遍历时避免直接修改集合
- 如果需要修改集合,可以先记录需要修改的内容,遍历结束后再统一修改。
- 示例:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); List<String> toRemove = new ArrayList<>(); for (String item : list) { if ("B".equals(item)) { toRemove.add(item); // 记录需要删除的元素 } } list.removeAll(toRemove); // 遍历结束后统一删除
4. 使用传统的 for 循环
- 如果需要通过索引修改集合,可以使用传统的
for
循环,但需要注意索引的正确性。 - 示例:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); for (int i = 0; i < list.size(); i++) { if ("B".equals(list.get(i))) { list.remove(i); // 直接通过索引删除 i--; // 调整索引 } }
5. 使用 Stream API(Java 8+)
- 使用
Stream
的filter()
方法可以避免直接修改集合。 - 示例:
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); list = list.stream() .filter(item -> !"B".equals(item)) .collect(Collectors.toList());
总结:
避免 ConcurrentModificationException
的关键在于:
- 使用迭代器的
remove()
方法修改集合。 - 使用并发集合类(如
CopyOnWriteArrayList
)。 - 遍历时避免直接修改集合,或者使用其他方法(如
Stream
)间接操作集合。
THE END
暂无评论内容