Java 8 中 Map 之 merge() 的用法

Java 8 最大的特性无异于更多地面向函数,比如引入了 lambda等,可以更好地进行函数式编程。前段时间无意间发现了 map.merge() 方法,感觉还是很好用的,此文简单做一些相关介绍。首先我们先看一个例子。

一:merge() 怎么用?

假如现在我们有个集合,集合中存放了各个学生各科的成绩,现在需要按学生敏子统计这个学生各科成绩的总分。

class StudentScore {
    private String name;

    private String subject;

    private Integer score;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public StudentScore(String name, String subject, Integer score) {
        this.name = name;
        this.subject = subject;
        this.score = score;
    }
}

 /*
     * @Author :chuxia0811
     * @Date: 2021/3/6  18:11
     * @Param:生成所有学生各科的成绩集合
     * @Return:
     * @Description :
     */

    public List<StudentScore> scoreinit() {
        List<StudentScore> scoreList = new ArrayList<>();
        scoreList.add(new StudentScore("张三", "java", 90));
        scoreList.add(new StudentScore("张三", "python", 95));
        scoreList.add(new StudentScore("张三", "php", 80));
        scoreList.add(new StudentScore("李四", "java", 88));
        scoreList.add(new StudentScore("李四", "python", 70));
        scoreList.add(new StudentScore("李四", "php", 98));
        scoreList.add(new StudentScore("王五", "java", 89));
        scoreList.add(new StudentScore("王五", "python", 76));
        scoreList.add(new StudentScore("王五", "php", 70));
        return scoreList;
    }

我们首先来看下常规的统计方法:

 /**
     * @Author :chuxia0811
     * @Date: 2021/3/6  18:19
     * @Param: 常规做法
     * @Return:
     * @Description :
     */

    public  void test1() {
        ObjectMapper objectMapper = new ObjectMapper();
        List<StudentScore> scores = scoreinit();
        Map<String,Integer> map = new HashMap<>();
        scores.forEach(score -> {
            if (map.containsKey(score.getName())){
                map.put(score.getName(),map.get(score.getName())+score.getScore());
            }else {
                map.put(score.getName(),score.getScore());
            }
        });
        try {
            System.out.println(objectMapper.writeValueAsString(map));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

打印结果如下:

{"李四":256,"张三":265,"王五":235}

我们再看下用merge()方法:

/*
    * @Author :chuxia0811
    * @Date: 2021/3/6  19:18
    * @Param:merge()方法
    * @Return: 
    * @Description :
   */
   
   public void test2(){
       ObjectMapper objectMapper = new ObjectMapper();
       Map<String,Integer> map = new HashMap<>();
       List<StudentScore> scores = scoreinit();
       scores.forEach(score -> map.merge(score.getName(),score.getScore(),Integer::sum));
       try {
           System.out.println(objectMapper.writeValueAsString(map));
       } catch (JsonProcessingException e) {
           e.printStackTrace();
       }
   }

打印结果如下:

 public static void main(String[] args) {
        Merge merge = new Merge();
        merge.test1();
        merge.test2();
    }
{"李四":256,"张三":265,"王五":235}
{"李四":256,"张三":265,"王五":235}

可以看出,结果一样,但用merge()方法会简单很多代码。

二:merge() 方法简介

merge() 可以这么理解:它将新的值赋值到 key (如果不存在)或更新给定的key 值对应的 value,其源码如下:

default V merge(K key, V value,
            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if(newValue == null) {
            remove(key);
        } else {
            put(key, newValue);
        }
        return newValue;
    }

我们可以看到原理也是很简单的,该方法接收三个参数,一个 key 值,一个 value,一个 remappingFunction ,如果给定的key不存在,它就变成了 put(key, value) 。

但是,如果 key 已经存在一些值,我们 remappingFunction 可以选择合并的方式,然后将合并得到的 newValue 赋值给原先的 key。

三:使用场景

这个使用场景相对来说还是比较多的,比如分组求和这类的操作,虽然 stream 中有相关 groupingBy() 方法,但如果你想在循环中做一些其他操作的时候,merge() 还是一个挺不错的选择的。

四:其他补充

除了 merge() 方法之外,我还看到了一些Java 8 中 map 相关的其他方法,比如 putIfAbsent 、compute() 、computeIfAbsent() 、computeIfPresent,这些方法我们看名字应该就知道是什么意思了,故此处就不做过多介绍了,感兴趣的可以简单阅读一下源码(都还是挺易懂的)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初夏0811

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值