如何优雅的删除HashMap元素

news/2024/7/17 4:24:49

文章目录

  • 1.数据准备
  • 2.删除方式
    • 2.1.使用增强 for 循环删除
    • 2.2.使用 forEach 循环删除
    • 2.3.使用 Iterator 迭代器删除
    • 2.4 使用 removeIf 删除(推荐使用)
    • 2.5.使用 Stream 删除(推荐使用)

1.数据准备

public Map<String, String> initMap = new HashMap<String, String>() {{put("user1", "刘零");put("user2", "郑一");put("user3", "吴二");put("user4", "张三");put("user5", "李四");put("user6", "王五");put("user7", "钱六");put("user8", "孙七");
}};

2.删除方式

2.1.使用增强 for 循环删除

/*** 使用 for 循环删除*/
public void remove1() {Set<Map.Entry<String, String>> entries = new CopyOnWriteArraySet<>(initMap.entrySet());for (Map.Entry<String, String> entry : entries) {if ("王五".equals(entry.getValue())) {initMap.remove(entry.getKey());}}System.out.println(initMap);
}

输出结果:
{user1=刘零, user2=郑一, user7=钱六, user8=孙七, user5=李四, user3=吴二, user4=张三}
通过HashMap的entrySet方法获取元素集合,然后再进行循环遍历,判断value值是否为需要删除的元素,再移除对应的Key。
需要注意增强的 for 循环底层使用的迭代器 Iterator,而 HashMap 是 fail-fast 原则的错误机制,所以遍历时删除元素会出现 java.util.ConcurrentModificationException 并发修改异常。我们可以使用CopyOnWriteArraySet封装一层避免出现并发修改异常。

  • fail-fast:为了将错误或异常情况尽早暴露出来,避免潜在的问题在后续代码中蔓延,提高系统的稳定性和可靠性。

2.2.使用 forEach 循环删除

/*** 使用 forEach 循环删除*/
public void remove2() {ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(initMap);map.forEach((k, v) -> {if ("王五".equals(v)) {map.remove(k);}});System.out.println(map);
}

输出结果:
{user1=刘零, user2=郑一, user7=钱六, user8=孙七, user5=李四, user3=吴二, user4=张三}
通过HashMap的forEach方法循环删除目标元素,同样的使用了ConcurrentHashMap封装避免出现并发修改异常。

2.3.使用 Iterator 迭代器删除

/*** 使用 Iterator 迭代器删除*/
@Test
public void remove3() {ConcurrentHashMap<String, String> resultMap = new ConcurrentHashMap<>();Iterator<Map.Entry<String, String>> iterator= new ConcurrentHashMap<>(initMap).entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, String> entry = iterator.next();if ("王五".equals(entry.getValue())) {iterator.remove();}else {resultMap.put(entry.getKey(),entry.getValue());}}System.out.println(resultMap);
}

输出结果:
{user1=刘零, user2=郑一, user7=钱六, user8=孙七, user5=李四, user3=吴二, user4=张三}
通过Iterator迭代删除元素不会出现并发修改异常,但由于HashMap是线程不安全的,这时如果多个线程同时修改HashMap数据也会出现并发修改异常 ,日常使用可以先用ConcurrentHashMap封装。

2.4 使用 removeIf 删除(推荐使用)

/*** 使用 removeIf 删除*/
public void remove4() {initMap.entrySet().removeIf(entry -> "王五".equals(entry.getValue()));System.out.println(initMap);
}

输出结果:
{user1=刘零, user2=郑一, user7=钱六, user8=孙七, user5=李四, user3=吴二, user4=张三}
通过entrySet获取元素然后使用removeIf方法删除目标数据;而removeIf的底层是通过Iterator迭代器实现的。所以也存在第三种方法同样的问题。

default boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);boolean removed = false;final Iterator<E> each = iterator();while (each.hasNext()) {if (filter.test(each.next())) {each.remove();removed = true;}}return removed;
}

2.5.使用 Stream 删除(推荐使用)

/*** 使用 Stream 删除*/
public void remove5() {Map<String, String> map = initMap.entrySet().stream().filter(entry -> !"王五".equals(entry.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));System.out.println(map);
}

输出结果:
{user1=刘零, user2=郑一, user7=钱六, user8=孙七, user5=李四, user3=吴二, user4=张三}
通过Stream 的 filter 方法进行过滤,然后生成一个新的map。这种方式“一行代码“就能够实现删除的动作,并且没有并发问题。


https://www.xjx100.cn/news/3091937.html

相关文章

面向对象程序设计1-类的定义和使用

第1关&#xff1a;数字时钟走字 任务描述 本关任务&#xff1a;本题中已给出一个时钟类的定义&#xff0c;请模拟数字时钟走字过程。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.类和对象。 编程要求 根据提示&#xff0c;在右侧编辑器补充代码&…

substring-after用法

substring-after&#xff1a;函数返回一个字符串&#xff0c;该字符串是给定子字符串后给定字符串的其余部分。 #句法 substring-after( haystack ,needle) haystack&#xff1a;要评估的字符串。该字符串的一部分将被返回。 needle&#xff1a;要搜索的子字符串。needle在h…

js实现页面滚动时自动切换Sidebar标签,点击标签自动滚动页面

js实现页面滚动时自动切换Sidebar侧边导航标签&#xff0c;点击标签自动滚动页面 <van-sidebar class"sidebar" v-model"activeKey"><van-sidebar-item :title"i.title" click"onChange(i)" v-for"(i,k) in activeList&…

关于校园网使用罗技flow功能

目录 情况概述问题及解决方案 情况概述 我目前设备是一台Macbook air m1处理器&#xff0c;学校给配了一台windows台式&#xff0c;台式机不能连蓝牙&#xff0c;不能连wifi&#xff0c;只能用网线&#xff0c;我的需求是想让mac和windows共用一套键鼠&#xff0c;在了解到罗技…

magisk 手机卡重启界面记录

中午发现手机自动关机了&#xff0c;开机后无限卡重启界面&#xff0c;但是可以进 rec 和 fastboot。怀疑是之前安装的 magisk 模块导致卡重启。不过值得一提的是&#xff0c;虽然自动关机的问题此前也出现过几次&#xff0c;但是都没有出现过卡重启的情况。 解决问题 进 rec …

【python学习】基础篇-常用模块-shutil文件和目录操作

shutil模块是Python标准库中的一个模块&#xff0c;提供了对文件和目录进行高级操作的函数。 以下是shutil模块的一些常用函数&#xff1a; 1.复制文件&#xff1a; 将源文件src复制到目标文件dst。如果follow_symlinks为True,则会跟随符号链接。 shutil.copy(src, dst, *, f…

企业app软件定制开发的重点是什么?|小程序网站搭建

企业app软件定制开发的重点是什么&#xff1f;|小程序网站搭建 在当今数字化时代&#xff0c;企业对于信息技术的依赖越来越大。为了适应市场需求并提高内部运营效率&#xff0c;许多企业开始寻求定制开发企业app软件。这种定制开发可以根据企业的具体需求和业务流程进行个性化…

活动回顾 | 数字外贸私享会【上海站】成功举办

11月17日&#xff0c;由箱讯科技主办的数字外贸高端定制私享会【上海站】成功举办&#xff01;本次会议的主题为“新模式、新商机、新政策”&#xff0c;外贸行业的老板、企业家们齐聚一堂&#xff0c;凝聚共识&#xff0c;共话数字外贸的新趋势和新机遇。 近年来&#xff0c;数…