当前位置: 首页 > 后端技术 > Java

面试官:如何删除HashMap中的元素?一行代码就搞定了,赶快用起来吧!

时间:2023-04-02 01:14:25 Java

背??景介绍大家好,我是堆栈管理员。前几天栈长给大家分享了两篇有趣的文章:3年的开发,我不会循环删除List中的元素,我直接崩溃了!!面试官:如何去除List中的重复元素?一行代码就搞定了,赶快用起来吧!这两篇文章确实可以帮助到一大批人。其中分享的一些实现技巧,可能很多年编程高手都没有用过。不管你多么优秀,多么谦虚好学,多掌握一点也不是坏事。有粉丝建议stackgrow一篇删除HashMap中数据的文章,也有粉丝建议系列文章:那么这篇文章就分享如何删除HashMap中的元素!PS:这只是我个人掌握的实施方案。它不一定是完整的或最佳的。欢迎大家分享。HashMap删除元素方案假定以下数据:publicMapinitMap=newHashMap<>(){{put("user1","ZhangSan");put("user2","李四");put("user3","张三");put("user4","李四");put("user5","王舞");put("user6","赵六");put("user7","李四");put("user8","王舞");}};本文所有完整示例源码已上传:https://github.com/javastacks...欢迎Star学习,后期Java示例将在此提供!一般是删除HashMap集合中的元素。如果知道具体的Key,需要根据Key删除元素,可以使用remove方法。但是如何根据Value删除HashMap集合中的元素呢?这是你必须掌握的技能!1.使用for循环删除/***使用for循环删除*@author:栈长*@from:公众号Java技术栈*/@Testpublicvoidremove1(){Set>entries=newCopyOnWriteArraySet<>(initMap.entrySet());for(Map.Entryentry:entries){if("张三".equals(entry.getValue())){initMap.remove(entry.getKey());}}}System.out.println(initMap);}输出结果:{user2=李四,user7=李四,user8=王五,user5=王五,user6=赵六,user4=李四}使用entrySet方法HashMap中实现获取元素集合,然后进行循环遍历,先根据Value值判断要删除的元素,再根据Key删除元素。在上一篇文章中我们知道,增强的for循环底层使用的迭代器Iterator,而HashMap是一种fail-fast类型的错误机制,所以遍历时删除元素会导致java.util.ConcurrentModificationException并发修改异常。所以这里使用线程安全的CopyOnWriteArraySet来封装一层避免并发修改异常。java.util.concurrent包中的并发集合类都设计成fail-safe(安全失败)类型,比如CopyOnWrite*,ConcerrentHashMap集合在遍历过程中改变结构是安全的,不会抛出上述异常.需要注意的是,虽然CopyOnWriteArraySet的并发性能很好,但是每次删除都会复制一个等价的set,所以要考虑数据过多可能带来的内存消耗问题。具体使用和实现原理可以点击CopyOnWriteArraySet关键字链接阅读上一篇文章,这里就不写了。2.使用forEach循环删除/***使用forEach循环删除*@author:栈长*@from:公众号Java技术栈*/@Testpublicvoidremove2(){ConcurrentHashMapmap=newConcurrentHashMap<>(initMap);map.forEach((k,v)->{if("张三".equals(v)){map.remove(k);}});System.out.println(地图);}输出结果:{user2=李四,user7=李四,user8=王五,user5=王五,user6=赵六,user4=李四}使用HashMap自带的forEach循环删除指定的元素值,为什么这里用一个线程安全的ConcurrentHashMap集合包裹一层,也是为了避免并发修改异常。ConcurrentHashMap在各个版本中都使用了最优的锁设计方案,并发性能也非常好。另外,HashMap和ConcurrentHashMap也是面试必问的问题。如果近期打算面试跳槽,建议在Java面试库小程序在线刷题,涵盖2000+道Java面试题,涵盖几乎所有主流技术面试题。3.使用Iterator迭代器删除/***使用Iterator迭代器删除*@author:栈长*@from:公众号Java技术栈*/@Testpublicvoidremove3(){Iterator>iterator=initMap.entrySet().iterator();while(iterator.hasNext()){Map.Entryentry=iterator.next();if("张三".equals(entry.getValue())){iterator.remove();}}System.out.println(initMap);}输出结果:{user2=Lisi,user7=Lisi,user8=Wangwu,user5=Wangwu,user6=ZhaoLiu,user4=LiSi}这个方法是用迭代器来正常遍历删除,不会导致并发修改异常。需要注意的是,虽然该方法不会导致并发修改异常,但是HashMap并不是线程安全的。迭代删除元素时,另一个线程可能会删除HashMap中的数据。这时候使用迭代器删除也会导致并发修改异常。因此,为了保证线程安全的删除,可以在创建迭代器之前用线程安全的ConcurrentHashMap集合包裹一层。或者使用synchronized关键字锁定整个Map。如果没有多线程修改环境,可以忽略。4.使用removeIf删除/***使用removeIf删除*@author:栈长*@from:公众号Java技术栈*/@Testpublicvoidremove4(){initMap.entrySet().removeIf(entry->"张三".equals(entry.getValue()));System.out.println(initMap);}输出结果:{user2=李四,user7=李四,user8=王五,user5=王五,user6=赵六,user4=李四}利用entrySet的removeIf来删除,它在底部使用迭代器:defaultbooleanremoveIf(Predicatefilter){Objects.requireNonNull(filter);布尔值移除=false;finalIteratoreach=iterator();while(each.hasNext()){if(filter.test(each.next())){each.remove();删除=真;}}returnremoved;}所以,它和方法3是一样的,只是把condition写成了Predicate函数接口。需要注意的是,removeIf虽然更方便,但仍然不是线程安全的。多线程场景参考方案同方法三。5.使用Stream删除/***使用Stream删除*@author:stacklength*@from:公众号Java技术栈*/@Testpublicvoidremove5(){Mapmap=initMap.entrySet().stream().filter(entry->!"张三".equals(entry.getValue())).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));系统。out.println(map);}输出结果:{user2=李四,user7=李四,user8=王五,user5=王五,user6=赵六,user4=李四}使用Stream的filter方法进行过滤,这个方法也很简单,一行代码。我不会介绍Stream的基础知识。我之前写过关于Stream系列的主题。不懂的可以关注公众号Java技术栈,然后在公众号Java教程菜单中阅读。本文所有完整示例源码均已上传:https://github.com/javastacks...欢迎Star学习,这??里将提供以下Java示例!总结本文总结了5种删除HashMap元素的方式:使用for循环删除使用forEach循环删除使用Iterator删除使用removeIf删除使用Stream删除在实际开发过程中,可能会使用不同的遍历方式,所以很重要在考虑多线程的场景中,如果单纯删除元素,使用removeIf和Streamfilter是最方便的。那么,你身边还有谁不会删除HashMap中的元素呢?把这篇文章发给他,让大家少走弯路,少写垃圾代码,共同进步。您还知道哪些其他删除技术?欢迎留言分享~好了,今天的分享就到这里了,稍后栈长会分享更多有趣的Java技术和最新的技术资料,关注公众号Java技术栈第一时间推送,我也会Java面试主流题库和参考答案已经整理完毕,大家可以使用Java面试库小程序刷题。最后留个话题:以上方法虽然可以删除HashMap中指定值的元素,但是不能删除所有重复的元素。您认为如何删除重复数据比较好?有什么选择?可以先讨论下一个方案,下期再分享。当栈长写完后,公众号JavaTechnologyStack会第一时间推送。别走~版权声明:本文由公众号《Java技术栈》原创,转载引用本文请注明内容出处,抄袭、洗稿均属侵权投诉,本站后果自负,保留追究法律责任的权利。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!