modcount在clear()中仅递增1次,因其本质是结构修改计数器而非元素数量映射;无论集合空或含百万元素,clear()均触发一次modcount++以保障fail-fast机制正确性。

Java中modCount在clear()方法中递增,不是因为要“加多少”,而是每次调用clear()都严格执行一次modCount++——无论集合原本有多少元素。
modCount 的本质是操作计数器,不是元素数量映射
modCount(modification count)是Java集合框架中用于检测并发修改的标记变量,类型为int,初始值为0。它不记录删除了多少个元素,只记录“结构修改”发生的次数。清空集合属于结构性修改(改变了容器大小和内部引用关系),所以必须触发一次递增。
- 哪怕集合为空,调用
clear()仍会执行modCount++ - 哪怕集合有100万个元素,
clear()也只让modCount增加1 - 这个递增发生在实际清空逻辑之前或之后(取决于具体实现),但一定发生且仅发生一次
ArrayList 和 LinkedList 的 clear 实现对比
两者都遵循“一次操作、一次计数”原则,但清空方式不同:
-
ArrayList.clear():把所有元素索引位置设为
null(避免内存泄漏),再将size = 0,最后modCount++ -
LinkedList.clear():遍历双向链表,逐个断开
prev/next引用并置空item,最后size = 0,再modCount++
注意:遍历断开节点是清理动作,modCount只在末尾统一加1,不会为每个节点加1。
为什么不能跳过或合并 modCount 递增?
这是fail-fast机制的核心保障。迭代器在创建时会记录当前modCount快照(expectedModCount),后续每次调用next()或hasNext()都会校验是否一致。
- 若
clear()不递增modCount,迭代器就无法感知集合已被清空,可能继续遍历已失效的引用,导致数据错乱或NullPointerException - 若对同一次
clear()做多次递增(如按元素数累加),反而会让迭代器提前抛出ConcurrentModificationException,破坏语义一致性
自定义集合中 clear 的正确写法
如果你实现自己的集合类并支持fail-fast,clear()中必须且只能有一次modCount++:
- 放在清空逻辑完成后(确保状态已变更)
- 不要放在循环内,也不要根据清空元素个数动态计算增量
- 即使清空逻辑本身抛出异常,也建议在
finally块中递增(或确保计数与实际修改严格对应)
例如:错误写法:for (int i = 0; i ;<font color="green">正确写法</font>:<code>doClear(); size = 0; modCount++;
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











