You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中删除HashMap元素时出现ConcurrentModificationException问题

解决HashMap遍历删除元素时的ConcurrentModificationException问题

这个问题我之前也碰到过!原因很简单——HashMap的迭代器是fail-fast机制的,当你在遍历entrySet的同时直接调用map.remove()修改原集合的结构,迭代器会检测到这个变化,立刻抛出ConcurrentModificationException来提醒你操作不安全。下面给你几种靠谱的解决办法:

1. 使用迭代器的remove()方法(传统安全方案)

这是Java集合框架推荐的遍历删除方式,迭代器的remove()方法会同步更新迭代器和原集合的状态,不会触发异常:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.stream.IntStream;

public class HelloWorld{
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        IntStream.range(0, 20).forEach(i -> map.put(Integer.toString(i), i % 2 == 0 ? null : "ok"));
        
        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            if (entry.getValue() == null) {
                iterator.remove(); // 用迭代器的remove方法,而非map的remove
            }
        }
    }
}

2. 使用Java 8+的removeIf方法(最简洁方案)

Java 8为集合新增了removeIf方法,它内部会安全地使用迭代器完成删除操作,代码非常简洁:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;

public class HelloWorld{
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        IntStream.range(0, 20).forEach(i -> map.put(Integer.toString(i), i % 2 == 0 ? null : "ok"));
        
        // 直接通过entrySet的removeIf过滤掉value为null的条目
        map.entrySet().removeIf(entry -> entry.getValue() == null);
    }
}

3. 先收集待删除的Key,再批量删除(兼容旧版本的变通方案)

如果你的项目还在用Java 8之前的版本,可以先把所有需要删除的Key收集到一个列表里,再遍历列表删除——这样遍历的是独立的列表,不会触发原map的迭代器检测:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

public class HelloWorld{
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        IntStream.range(0, 20).forEach(i -> map.put(Integer.toString(i), i % 2 == 0 ? null : "ok"));
        
        List<String> keysToRemove = new ArrayList<>();
        // 先收集所有value为null的key
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue() == null) {
                keysToRemove.add(entry.getKey());
            }
        }
        // 再批量删除
        for (String key : keysToRemove) {
            map.remove(key);
        }
    }
}

4. 使用Stream API生成新Map(不修改原Map的场景)

如果不需要修改原Map,而是要得到一个过滤后的新Map,用Stream API会很优雅:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class HelloWorld{
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        IntStream.range(0, 20).forEach(i -> map.put(Integer.toString(i), i % 2 == 0 ? null : "ok"));
        
        // 过滤出value不为null的条目,收集成新的HashMap
        Map<String, String> filteredMap = map.entrySet().stream()
                .filter(entry -> entry.getValue() != null)
                .collect(Collectors.toMap(
                        Map.Entry::getKey, 
                        Map.Entry::getValue,
                        (oldVal, newVal) -> oldVal, // 处理key冲突的逻辑(这里用旧值)
                        HashMap::new // 指定收集为HashMap
                ));
    }
}

内容的提问来源于stack exchange,提问作者Sk. Irfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:09:34