遍历中删除元素会导致跳过后续元素,因索引变动而循环步进逻辑未同步调整;应反向遍历、收集后统一删除或改用迭代器安全移除。
因为遍历和删除同时发生时,列表的索引结构被动态打乱,而循环仍按原定步进逻辑推进,结果跳过了刚前移过来的元素。
下标递增遍历时删除会改变后续元素位置
比如列表是 [1, 2, 3, 4, 5],用 for (int i = 0; i 遍历,当 <code>i == 1 时取到元素 2;若此时删掉 2,列表变成 [1, 3, 4, 5],原来在索引 2 的 3 就自动挪到了索引 1。但循环下一步是 i++ 变成 2,直接去取新列表中索引 2 的 4,于是 3 就被跳过了。
连续满足删除条件时漏删更明显
像 [2, 8, 8, 6, 4, 8, 8],要删所有 8:
- 第一次删掉索引 1 的 8 → 列表变为 [2, 8, 6, 4, 8, 8](第二个 8 移到索引 1)
- 下一轮 i 变成 2,取的是 6,中间那个刚移上来的 8 完全没被检查
- 后续同理,导致最终剩下多个 8
根本矛盾在于“读位置”和“写动作”不同步
for 循环依赖一个固定的索引增长节奏(i++),但 remove() 每次都会让后面所有元素向前缩一位——相当于一边走路一边抽掉脚下的砖。循环不感知这个变化,只机械地走下一步,自然踩空。
安全删除的常用做法
- 用 迭代器的 remove() 方法:它内部会同步维护当前游标位置,删完自动适配
- 改为 倒序遍历(i = list.size()-1; i >= 0; i--):删后面的不影响前面的索引
- 先收集待删元素,遍历结束后统一删:避免边读边改,逻辑清晰不易错

















