使用Iterator迭代器在遍历中安全删除元素

前言

最近在开发过程中遇到一个异常抛出,不能在for循环中对集合元素进行删除,小记一下这个方法!

🔍 一、什么是 Iterator?

Iterator 是 专门用于遍历集合(List / Set)并允许在遍历中安全删除元素的接口 。它是 Java Collection 框架的重要成员,避免 foreach 删除时报 ConcurrentModificationException。

支持的集合:

集合类型 是否支持 Iterator
List ✔
Set ✔
Map ❌(需要转 entrySet)

📌 二、Iterator 的核心方法

方法 作用
hasNext() 是否还有下一个元素
next() 取出下一个元素
remove() 删除当前元素(只能在 next() 后调用)

🚀 三、最常用的迭代器遍历写法(标准写法)

plain 复制代码
Iterator<Long> iterator = ids.iterator();
while (iterator.hasNext()) {
    Long id = iterator.next();
    System.out.println(id);
}

🧹 四、遍历中安全删除元素(必须使用 iterator.remove())

plain 复制代码
Iterator<Long> iterator = ids.iterator();
while (iterator.hasNext()) {
    Long id = iterator.next();
    if (id < 10) {
        iterator.remove();  // ❗必须使用 iterator.remove()
    }
}

❌ 五、错误写法(一定会报错)

plain 复制代码
for (Long id : ids) {
    ids.remove(id);   // ❌ ConcurrentModificationException
}

🔁 六、遍历 Set 集合

plain 复制代码
Set<String> names = new HashSet<>();
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
    String name = iterator.next();
    System.out.println(name);
}

🔑 七、遍历 Map(需要转换为 entrySet)

plain 复制代码
Map<Long, String> map = new HashMap<>();

Iterator<Map.Entry<Long, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<Long, String> entry = iterator.next();
    System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue());
}

✨ 八、增强版写法:统计 + 删除 + 记录日志

plain 复制代码
List<Long> removedIds = new ArrayList<>();
Iterator<Long> iterator = ids.iterator();

while (iterator.hasNext()) {
    Long id = iterator.next();
    if (!filesMapper.isExist(id)) {
        removedIds.add(id);
        iterator.remove();
    }
}

log.info("共删除 {} 个无效 ID:{}", removedIds.size(), removedIds);

📚 九、Iterator vs forEach vs Stream

遍历方式 是否能删除 是否推荐
for-each ❌ 不推荐删除
Iterator ✔ CRUD 通用推荐
removeIf ✔ JDK8 最简洁
Stream ❌ 可过滤但不可直接删除

🌟 十、JDK8 更推荐:removeIf

plain 复制代码
ids.removeIf(id -> !filesMapper.isExist(id));

📌 十一、Iterator 常见错误总结

错误写法 后果
ids.remove(id) 报 ConcurrentModificationException
iterator.remove() 但没有 next() IllegalStateException
用了两次 remove() IllegalStateException
修改集合长度时继续遍历 逻辑错误

✔ 十二、Iterator 使用场景总结

使用场景 是否适合用 Iterator
安全删除集合元素 ✔ 必须
简单遍历 可用,但 forEach 更快
大量数据遍历 ✔
删除元素并记录日志 ✔
Map 遍历 ✔(需 entrySet)
Stream 操作 ❌ 不能直接删除

🎯 总结一句话

👉 Iterator 是遍历集合并安全删除元素的唯一方式(forEach ×)。

相关推荐
专业程序开发源6 分钟前
springboot校企合作双选会一站式预约与面试系统16010-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·面试·php·课程设计
郑州光合科技余经理1 小时前
同城商城源码:商品库和订单库怎么随包交付
android·java·开发语言·后端·uni-app·php·ai编程
\光辉岁月/1 小时前
4.String类
java·面向对象·stringbuilder·string·stringbuffer·字符串类
蚰蜒螟1 小时前
从 Java SocketChannel 到 TCP 挥手:一次 close() 的完整调用链与引用计数解析
java·python·tcp/ip
damoluomu1 小时前
国产 Java CMS 的协议和坑,讲清楚
java·开发语言
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 黑名单:分页查询黑名单
java·开发语言·交友
蚰蜒螟1 小时前
从 Java write 到磁盘扇区:一次写入操作的完整内核穿越之旅
java·开发语言
en.en..2 小时前
volatile 关键字整理(嵌入式 C 标准)
java·开发语言
captain3762 小时前
Spring IoC和DI(2)
java·后端·spring