Java中Map循环安全的删除数据的4中方法

server/2025/2/22 7:51:44/

文章目录

  • 前言
  • 一、使用Iterator删除
  • 二、使用 removeIf(Java 8+)
  • 三、遍历时记录需要删除的键(不推荐)
  • 四、使用 Stream(Java 8+)
  • 总结


前言

在 Java 中,遍历 HashMap 并删除数据时,直接使用 for-each 循环或 Iterator 的 remove 方法可能会导致 ConcurrentModificationException 异常。为了避免这个问题,需要使用 Iterator 来安全地删除数据。


以下是常见的4中删除方法

一、使用Iterator删除

这种事最安全的方式!也是最推荐的一种方法!

java">import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;public class Main {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("A", 1);map.put("B", 2);map.put("C", 3);// 使用 Iterator 遍历并删除Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, Integer> entry = iterator.next();if (entry.getValue() == 2) { // 删除值为 2 的条目iterator.remove(); // 安全删除}}System.out.println(map); // 输出: {A=1, C=3}}
}

说明:

  • 使用iterator.remove() 方法删除当前的数据,并不是直接操作HahsMap
  • 这种方法不会引发ConcurrentModificationException 报错

二、使用 removeIf(Java 8+)

如果你使用的是 Java 8 或更高版本,可以使用 removeIf 方法,这是一种更简洁的方式。

java">import java.util.HashMap;public class Main {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("A", 1);map.put("B", 2);map.put("C", 3);// 使用 removeIf 删除符合条件的条目map.entrySet().removeIf(entry -> entry.getValue() == 2);System.out.println(map); // 输出: {A=1, C=3}}
}

说明:

  • removeIf 是 Collection 接口的方法,HashMap 的 entrySet() 返回一个集合,因此可以直接使用。
  • 代码更简洁,适合 Java 8 及以上版本。

三、遍历时记录需要删除的键(不推荐)

如果你不想使用 Iterator 或 removeIf,可以先记录需要删除的键,然后再统一删除。这种方式不推荐,因为需要额外的空间。

java">import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;public class Main {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("A", 1);map.put("B", 2);map.put("C", 3);// 记录需要删除的键Set<String> keysToRemove = new HashSet<>();for (Map.Entry<String, Integer> entry : map.entrySet()) {if (entry.getValue() == 2) {keysToRemove.add(entry.getKey());}}// 统一删除for (String key : keysToRemove) {map.remove(key);}System.out.println(map); // 输出: {A=1, C=3}}
}

说明:

  • 需要额外的集合(如 HashSet)来存储需要删除的键。
  • 不推荐,因为代码冗长且效率较低。

四、使用 Stream(Java 8+)

如果你喜欢函数式编程风格,可以使用 Stream 来过滤并生成新的 HashMap。

java">import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;public class Main {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("A", 1);map.put("B", 2);map.put("C", 3);// 使用 Stream 过滤并生成新的 HashMapMap<String, Integer> filteredMap = map.entrySet().stream().filter(entry -> entry.getValue() != 2).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));System.out.println(filteredMap); // 输出: {A=1, C=3}}
}

说明:

  • 使用 Stream 过滤数据并生成一个新的 HashMap。
  • 适合需要保留原 HashMap 的场景。

总结

  • 方法1 -Iterator 安全,直接操作原 HashMap 代码稍显冗长 需要直接修改原 HashMap
  • 方法2-removeIf 简洁,适合 Java 8+ 需要 Java 8 或更高版本 需要直接修改原 HashMap
  • 方法3-记录键后删除 无需 Iterator 需要额外空间,效率较低 不推荐
  • 方法4-Stream 函数式风格,生成新 HashMap 需要额外空间,生成新对象 需要保留原 HashMap

http://www.ppmy.cn/server/169042.html

相关文章

vue 接口传formdata

在Vue中&#xff0c;如果你需要向服务器发送FormData对象&#xff0c;通常是为了上传文件或者需要发送表单数据。FormData是一个非常有用的工具&#xff0c;因为它可以直接使用表单元素的值以及文件内容&#xff0c;并以一种浏览器兼容的方式来发送这些数据。下面是如何在Vue中…

Zoho Books:简单好用的外贸订单管理系统,外贸跟单自动化处理

在全球贸易日益紧密的今天&#xff0c;外贸行业蓬勃发展&#xff0c;但外贸订单的跟单工作却让许多从业者头疼不已。如何高效管理订单&#xff0c;确保货物按时、按质交付&#xff0c;成为外贸企业提升竞争力的关键。这时候&#xff0c;一款优秀的外贸订单管理系统就显得尤为重…

pytest asyncio 支持插件 pytest-asyncio

pytest 是 Python 测试框架&#xff0c;但其不支持基于 asyncio 的异步程序&#xff08;例如&#xff0c;测试 FastAPI 异步代码&#xff09;&#xff0c;pytest-asyncio 是一个 pytest 插件&#xff0c;该插件赋予 pytest 可以测试使用 asyncio 库代码的能力。 https://github…

[AI]Mac本地部署Deepseek R1模型 — — 保姆级教程

[AI]Mac本地部署DeepSeek R1模型 — — 保姆级教程 DeepSeek R1是中国AI初创公司深度求索&#xff08;DeepSeek&#xff09;推出大模型DeepSeek-R1。 作为一款开源模型&#xff0c;R1在数学、代码、自然语言推理等任务上的性能能够比肩OpenAI o1模型正式版&#xff0c;并采用MI…

Mac访问局域网Jenkins

主要修改两个文件 第一个是 &#xff5e;/Library/LaunchAgents/homebrew.mxcl.jenkins.plist 第二个 ⚠️注意如果是使用 brew 安装的 Jenkins 可以在终端执行brew info jenkins查看你安装 Jenkins 的路径&#xff0c;执行完看控制台 比如我的是 ~ % brew info jenkins >…

级联选择器多选动态加载

一.级联展示 注&#xff1a;因为级联选择器这里是动态加载&#xff0c;因此如果上来选中一级就需要加载出后面三级的全部数据&#xff0c;依然会很卡&#xff0c;因此&#xff0c;和产品协商把一二级多选框去掉了&#xff0c;这样也避免了你选择一级不能实现子级被全部选中的问…

使用nginx+rtmp+ffmpeg实现桌面直播

使用nginxrtmpffmpeg实现桌面直播 流媒体服务器搭建 docker run docker镜像基于添加了rtmp模块的nginx&#xff0c;和ffmpeg docker pull alfg/nginx-rtmp docker run -d -p 1935:1935 -p 8080:80 --namenginx-rtmp alfg/nginx-rtmprtmp模块说明 进入容器内部查看 docker…

【核心算法篇三】《DeepSeek强化学习:Atari游戏训练框架解析》

大家好,今天我们来聊聊一个非常酷的话题——DeepSeek强化学习框架,特别是它在Atari游戏训练中的应用。如果你对人工智能、机器学习或者游戏AI感兴趣,那么这篇文章绝对不容错过。我们会从基础概念讲起,逐步深入到DeepSeek的核心原理和实现细节,最后还会探讨一些实际应用中的…