Java8最大的特点就是更加面向函数,比如引入了lambda等,可以更好的进行函数式编程。前段时间无意中发现了map.merge()这个方法,感觉很好用。本文简要介绍一些相关信息。首先让我们看一个例子。如何使用合并()?假设我们有这么一段业务逻辑。我有一个学生成绩对象列表。该对象包含三个属性:学生姓名、科目和科目分数。要求获得每个学生的总成绩。加入列表如下:privateListbuildATestList(){ListstudentScoreList=newArrayList<>();StudentScorestudentScore1=newStudentScore(){{setStuName("张三");setSubject("Chinese");setScore(70);}};StudentScorestudentScore2=newStudentScore(){{setStuName("张三");setSubject("数学");setScore(80);}};StudentScorestudentScore3=newStudentScore(){{setStuName("张三");setSubject("英文");setScore(65);}};StudentScorestudentScore4=newStudentScore(){{setStuName("李四");setSubject("中文");setScore(68);}};StudentScorestudentScore5=newStudentScore(){{setStuName("李四");setSubject("数学");setScore(70);}};StudentScorestudentScore6=newStudentScore(){{setStuName("李四");setSubject("英语");setScore(90);}};StudentScorestudentScore7=newStudentScore(){{setStuName("王武");setSubject("中文");setScore(80);}};StudentScorestudentScore8=newStudentScore(){{setStuName("王五");setSubject("数学");setScore(85);}};StudentScorestudentScore9=newStudentScore(){{setStuName("王五");setSubject("英语");setScore(70);}};studentScoreList.add(studentScore1);studentScoreList.add(studentScore2);studentScoreList.add(studentScore3);studentScoreList.add(studentScore4);studentScoreList.add(studentScore5);studentScoreList.add(studentScore6);studentScoreList.add(studentScore7);studentScoreList.add(studentScore8);studentScoreList.add(studentScore9);returnstudentScoreList;}我们先看一下常规做法:ObjectMapperobjectMapper=newObjectMapper();ListstudentScoreList=buildATestList();MapstudentScoreMap=newHashMap<>();studentScoreList.forEach(studentScore->{if(studentScoreMap.containsKey(studentScore.getStuName())){studentScoreMap.put(studentScore.getStuName(),studentScoreMap.get(studentScore.getStuName())+studentScore.getScore());}else{studentScoreMap.put(studentScore.getStuName(),studentScore.getScore());}});System.out.println(objectMapper.writeValueAsString(studentScoreMap));//结果如下://{"李四":228"张三":215,"王五":235}然后看看merge()是怎么做的:MapstudentScoreMap2=newHashMap<>();studentScoreList.forEach(studentScore->studentScoreMap2.merge(studentScore.getStuName(),studentScore.getScore(),Integer::sum));System.out.println(objectMapper.writeValueAsString(studentScoreMap2));//结果如下://{"李四":228,"张三":215,"王五":235}merge()介绍merge()可以这样理解:给key赋一个新值(如果不存在)或者更新对应的value给定的键值。其源码如下:VnewValue=oldValue==null?value:remappingFunction.apply(oldValue,value);if(newValue==null){this.remove(key);}else{this.put(key,newValue);}returnnewValue;}我们可以看到原来的道理也很简单。这个方法接收三个参数,一个键值,一个值,一个remappingFunction。如果给定的键不存在,则变成put(key,value)但是,如果键已经有一些值,我们的remappingFunction可以选择合并方法,然后将合并后的新值分配给原始键。使用场景使用场景比较多,比如分组、求和等操作。虽然stream中有相关的groupingBy()方法,但是如果你想在循环中做一些其他的操作,merge()仍然是一个相当不错的选择。除了merge()方法,我还看到了Java8中其他一些和map相关的方法,比如putIfAbsent、compute()、computeIfAbsent()、computeIfPresent,这些方法看名字就应该知道是什么意思了,所以就不过多介绍了,有兴趣的可以直接看源码(还是比较容易理解的),这里贴出compute()(Map.class)的源码,它的返回值为计算后得到的新值oldValue);if(newValue==null){if(oldValue==null&&!this.containsKey(key)){returnull;}else{this.remove(key);returnull;}}else{this.put(key,newValue);returnnewValue;}}小结本文简单介绍了Map.merge()方法。另外,Java8中的HashMap实现方式使用了TreeNode和红黑树。源码可能读起来有点吃力,但是原理是差不多的,compute()是一样的。因此,必须阅读源代码。不懂的多看多练就会明白了。链接参考:https://www.jianshu.com/p/68e6b30410b0测试代码地址:https://github.com/lq920320/algorithm-java-test/blob/master/src/test/java/other/MapMethodsTest。爪哇