网易首页 > 网易号 > 正文 申请入驻

Map只会put、get?快来学这几个“新”方法

0
分享至

Java精选面试题 (微信小程序): 5000+ 道面试题和选择题, 真实面经 , 简历模版 ,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等,在线随时刷题!


Map的数据操作,你是不是还只会put、get?

Map是我们日常编程中十分常用的数据接口,的在JDK8中,Map引入了几个新方法,可以简化我们对Map中数据的操作。

目前JDK的最新LTS版本已经更新到21了,这几个在JDK8引入的Map”新“方法其实也是”老“方法了,还没熟练使用也太out了,快来看看你都”学废“了吗?


getOrDefault

这个方法名很直观,见名知意:尝试获取key对应的值,如果未获取到,就返回默认值。

看一个使用的例子,新写法会比老写法更加简洁:

private static void testGetOrDefault() {
    Map
     
  map = new HashMap<>(4);     map.put( "123",  "123");     String key =  "key";     String defaultValue =  "defaultValue";     // 老写法     String oldValue = defaultValue;      if (map.containsKey(key)) {         oldValue = map.get(key);     }     System.out.println( "oldValue = " + oldValue);     // 新写法     String newValue = map.getOrDefault(key, defaultValue);     System.out.println( "newValue = " + newValue); }
foreach

看方法名也可以知道,这个方法是遍历map的数据使用的。

如果没有foreach,我们遍历map的时候一般是使用增强for循环,有了这个方法后,可以更加方便使用entry中的key和val:

private static void testForeach() {
    Map
     
  map = new HashMap<>(4);     map.put( "123",  "123");     // 老写法      for (Map.Entry  entry : map.entrySet()) {         System.out.printf( "老写法 key = %s, value = %s%n", entry.getKey(), entry.getValue());     }     // 新写法     map.forEach((key, value) -> System.out.printf( "新写法 key = %s, value = %s%n", key, value)); }
merge

从名字可以想到,是合并entry使用的,但是具体是怎么合并呢?

看一下日常最常用的Map实现类HashMap对merge方法的实现。

推荐划水摸鱼神器: https://www.yoodb.com/slack-off/home.html

@Override
public V merge(K key, V value,
               BiFunction
     
 remappingFunction) {
    if (value == null || remappingFunction == null)
        throw new NullPointerException();
    int hash = hash(key);
    Node
     
 [] tab; Node  first; int n, i;     int binCount = 0;     TreeNode  t = null;     Node  old = null;      if (size > threshold || (tab = table) == null ||         (n = tab.length) == 0)         n = (tab = resize()).length;      if ((first = tab[i = (n - 1) &  hash]) != null) {          if (first instanceof TreeNode)             old = (t = (TreeNode )first).getTreeNode( hash, key);          else {             Node  e = first; K k;              do {                  if (e.hash ==  hash &&                     ((k = e.key) == key || (key != null && key.equals(k)))) {                     old = e;                      break;                 }                 ++binCount;             }  while ((e = e.next) != null);         }     }      if (old != null) {         V v;          if (old.value != null) {             int mc = modCount;             v = remappingFunction.apply(old.value, value);              if (mc != modCount) {                 throw new ConcurrentModificationException();             }         }  else {             v = value;         }          if (v != null) {             old.value = v;             afterNodeAccess(old);         }          else             removeNode( hash, key, null,  false,  true);          return v;     }  else {          if (t != null)             t.putTreeVal(this, tab,  hash, key, value);          else {             tab[i] = newNode( hash, key, value, first);              if (binCount >= TREEIFY_THRESHOLD - 1)                 treeifyBin(tab,  hash);         }         ++modCount;         ++size;         afterNodeInsertion( true);          return value;     } }

代码比较长,但是实现的效果比较容易描述:这个方法接收3个参数:key、value、function。

  • 如果key存在,将value按照function做1次计算后,更新到Map中

  • 如果key不存在,将key-value放入Map中

这个方法在某些场景中挺好用的,代码简洁易懂,例如:我们有1个List,要统计List中每个元素出现的次数。我们要实现的逻辑是,遍历List中的每个元素,如果这个元素在Map中存在,Map中的值+1;如果不存在,则放入Map中,次数(值)为1。

private static void testMerge() {
    Map
     
  cntMap = new HashMap<>(8);     List  list = Arrays.asList( "apple",  "orange",  "banana",  "orange");     // 老写法      for (String item : list) {          if (cntMap.containsKey(item)) {             cntMap.put(item, cntMap.get(item) + 1);         }  else {             cntMap.put(item, 1);         }     }     // 新写法      for (String item : list) {         cntMap.merge(item, 1, Integer::sum);     } }

可以看到我们使用merge方法的话,只用1行就简洁实现了这个逻辑。

putIfAbsent

也是一个见名知意的方法:不存在key或者值为null时,才将键值对放入Map。跟put方法相比,这个方法不会直接覆盖已有的值,在不允许覆盖旧值的场景使用起来会比较简洁。

private static void testPutIfAbsent() {
    Map
     
  scoreMap = new HashMap<>(4);     scoreMap.put( "Jim", 88);     scoreMap.put( "Lily", 90);     // 老写法      if (!scoreMap.containsKey( "Lily")) {         scoreMap.put( "Lily", 98);     }     // 新写法     scoreMap.putIfAbsent( "Lily", 98); }
computer

computer方法需要传入2个参数:key、function。主要有3步操作

  • 获取到key对应的oldValue,可能为null

  • 经过function计算获取newValue

  • put(key, newValue)

还是以刚刚统计单次次数需求为例,看一下computer的写法:

private static void testComputer() {
    Map
     
  cntMap = new HashMap<>(8);     List  list = Arrays.asList( "apple",  "orange",  "banana",  "orange");     // 老写法      for (String item : list) {          if (cntMap.containsKey(item)) {             cntMap.put(item, cntMap.get(item) + 1);         }  else {             cntMap.put(item, 1);         }     }     // 新写法      for (String item : list) {         cntMap.compute(item, (k, v) -> {              if (v == null) {                 v = 1;             }  else {                 v += 1;             }              return v;         });     } }
computeIfAbsent

看名字就知道是compute方法衍生出来的方法,这个方法只在key不存在的时候,执行computer计算,如果说key对应的value存在,就直接返回这个value。

例如,我们需要计算斐波那锲数列的时候,可以使用这个方法来简化代码:

private static void testComputerIfAbsent() {
    Map
     
  fabMap = new ConcurrentHashMap<>(16);     fabMap.put(0, 1);     fabMap.put(1, 1);     System.out.println(fab(5, fabMap)); } private static Integer fab(Integer index, Map  fabMap) {      return fabMap.computeIfAbsent(index, i -> fab(i - 2, fabMap) + fab(i - 1, fabMap)); }
computeIfPresent

这个是computeIfAbsent的姊妹方法,区别在于,这个方法是只有key存在的时候,才去执行computer计算和值的更新。

replace

这个方法的效果是:

  • 如果key存在,则更新值

  • 如果key不存在,什么也不做

总结

可以看到,这些JDK8引入的Map的方法,都可以在某些特定场景下简化我们的代码,虽然不嫌麻烦的话,put、get等方法都可以搞定,让我想起一张远古的图


不过在不同的场景使用不同的方法,尽量把代码写的简洁和优雅,才是一个程序猿不断追求的目标吧。

作者:podongfeng 来源:https://juejin.cn/post/7342420969879093299

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有技术或摸鱼交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!在线摸鱼:https://www.yoodb.com/

Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
愤怒!又有懦夫开车撞小学生!!

愤怒!又有懦夫开车撞小学生!!

近距离
2024-11-19 12:49:28
吹牛老爹与朴彩英视频被疯传,不雅画面太真实,粉丝迅速回应

吹牛老爹与朴彩英视频被疯传,不雅画面太真实,粉丝迅速回应

南城无双
2024-11-20 01:21:09
中石油原董事长贪腐数额特别巨大,到底多少?

中石油原董事长贪腐数额特别巨大,到底多少?

梦马笔谈
2024-11-19 19:26:36
太原17岁被围殴男孩母亲再发声:警方已行政立案,不接受任何调解

太原17岁被围殴男孩母亲再发声:警方已行政立案,不接受任何调解

极目新闻
2024-11-19 15:00:34
浙江大学本科生与其教授母亲同发论文受质疑,其母所在大学:将调查,会公正对待

浙江大学本科生与其教授母亲同发论文受质疑,其母所在大学:将调查,会公正对待

红星新闻
2024-11-18 19:13:17
女罪犯4年生3胎多次监外执行引热议,妇联回应!律师解读

女罪犯4年生3胎多次监外执行引热议,妇联回应!律师解读

鲁中晨报
2024-11-19 16:44:04
太恶心!网传广州车展惊现尴尬一幕,一女销售裙子沾染不明液体…

太恶心!网传广州车展惊现尴尬一幕,一女销售裙子沾染不明液体…

火山诗话
2024-11-19 07:12:29
广州:将在全市范围内收购满足90平米以下的存量商品房作为保障房

广州:将在全市范围内收购满足90平米以下的存量商品房作为保障房

界面新闻
2024-11-19 13:44:56
报复型社会或已形成,请注意这几类人群,外出提高警惕性

报复型社会或已形成,请注意这几类人群,外出提高警惕性

觉叔说
2024-11-19 17:49:59
原创丨中国这次打脸干得真漂亮,美国后院失火了!奖惩要分明,中国需狠狠教训他们!

原创丨中国这次打脸干得真漂亮,美国后院失火了!奖惩要分明,中国需狠狠教训他们!

占豪
2024-11-19 01:43:15
湖南常德这件事比想象还要恐怖

湖南常德这件事比想象还要恐怖

V记录号
2024-11-19 13:50:30
丰田公开搭载氢发动机的混合动力车

丰田公开搭载氢发动机的混合动力车

界面新闻
2024-11-18 11:50:01
0-5!0-2!世预赛一夜3场冷门,亚洲冠军惨败,沙特+韩国双双翻车

0-5!0-2!世预赛一夜3场冷门,亚洲冠军惨败,沙特+韩国双双翻车

阿柒体讯
2024-11-20 02:03:54
4队6分,彻底乱套!国足1-3日本塞翁失马,直接进世界杯机会大增

4队6分,彻底乱套!国足1-3日本塞翁失马,直接进世界杯机会大增

嘴炮体坛
2024-11-19 22:37:08
央视官宣后,台军不寒而栗,解放军“武统利器”,拦飞弹像拍苍蝇

央视官宣后,台军不寒而栗,解放军“武统利器”,拦飞弹像拍苍蝇

空天力量
2024-11-19 11:56:14
广东一女子在家躺平,姿势随意遭吐槽,男友:以前的淑女消失了

广东一女子在家躺平,姿势随意遭吐槽,男友:以前的淑女消失了

唐小糖说情感
2024-11-20 00:34:15
俄媒发布库尔斯克最新战况:近千名乌军被完全包围

俄媒发布库尔斯克最新战况:近千名乌军被完全包围

参考消息
2024-11-19 16:37:08
东北老虎进村最新后续:被咬农民大爷伤势严重,老虎进村原因曝光

东北老虎进村最新后续:被咬农民大爷伤势严重,老虎进村原因曝光

阿矗论古今
2024-11-19 15:22:27
美国将进入紧急状态,特朗普承认会出动美军,要对付马斯克之流?

美国将进入紧急状态,特朗普承认会出动美军,要对付马斯克之流?

猎火照狼山
2024-11-20 00:05:02
新发现?被扒妻女入美籍的涉军国企员工,疑为该司纪检与审计法律部部长

新发现?被扒妻女入美籍的涉军国企员工,疑为该司纪检与审计法律部部长

不掉线电波
2024-11-19 17:22:05
2024-11-20 04:39:00
Java精选
Java精选
一场永远也演不完的戏
1589文章数 3853关注度
往期回顾 全部

科技要闻

小鹏Q3营收破百亿,交付4.7万辆,亏18.1亿

头条要闻

国足1比3不敌日本 征战18强赛的最大顽疾被对手再利用

头条要闻

国足1比3不敌日本 征战18强赛的最大顽疾被对手再利用

体育要闻

15胜0负的骑士,真的在模仿勇士

娱乐要闻

金鸡奖颁奖,流量至上,都在座位表上体现了

财经要闻

专家称我国还缺1亿套保障房

汽车要闻

后排够大 智能化提升 全新探岳L是你的菜么?

态度原创

艺术
亲子
时尚
房产
公开课

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

亲子要闻

生了孩子还能这么玩?

50岁贝嫂:生孩子不会变老,穷和不自律才会

房产要闻

重磅!海南取消限购第8城来了!楼市限购,还剩10城

公开课

一块玻璃,如何改变人类世界?

无障碍浏览 进入关怀版