Java8中如何合并两个map

如何处理Map含有重复元素的情况

1. 初始化

我们定义两个map实例

private static Map<String, People> map1 = new HashMap<>();
private static Map<String, People> map2 = new HashMap<>();

People类

class People {private Long id;private String name;public People(Long id, String name) {this.id = id;this.name = name;}......}然后往map中存入一些数据static {People people1 = new People(1L, "Henry");map1.put(people1.getName(), people1);People people2 = new People(2L, "Annie");map1.put(people2.getName(), people2);People people3 = new People(3L, "John");map1.put(people3.getName(), people3);People people4 = new People(4L, "George");map2.put(people4.getName(), people4);People people5 = new People(5L, "Henry");map2.put(people5.getName(), people5);}

特别需要注意的是_people1_和_people5__在map中有完全相同的key(name)。_

2.Map.merge()

Java8为**java.util.Map接口新增了merge()函数。**

merge() 函数的作用是: 如果给定的key之前没设置value 或者value为null, 则将给定的value关联到这个key上.

否则,通过给定的remaping函数计算的结果来替换其value。如果remapping函数的计算结果为null,将解除此结果。

// 通过拷贝map1中的元素来构造一个新的HashMap
Map<String, People> map3 = new HashMap<>(map1);
// 引入merge函数和合并规则 map3.merge(key, value, (v1, v2) -> new People(v1.getId(), v2.getName())
// map2进行迭代将其元素合并到map3中
map2.forEach((key, value) -> map3.merge(key, value, (v1, v2) -> new People(v1.getId(), v2.getName())));
printMap("map3", map3);
/*** map3:* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* George:People{id=4, name='George'}* Henry:People{id=1, name='Henry'}*/

最终,通过结果可以看出,实现了两个map的合并,对重复的key也合并为同一个元素。

注意最后一个_People_的id来自map1而name来自map2.

原因是我们的merge函数的定义:

(v1, v2) -> new People(v1.getId(), v2.getName())

3.Stream.concat()

_Java8的Stream_API 也为解决该问题提供了较好的解决方案。

首先需要将两个map合为一个**Stream。**

Stream combined = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream());

我们需要将entry sets作为参数,然后利用_Collectors.toMap()_:将结果放到新的map中。

 try {Map<String, People> map4 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));printMap("map4", map4);} catch (IllegalStateException e) {System.out.println("Error: " + e);}

该方法可以实现map的合并,但是有重复key会报_IllegalStateException异常。_

为了解决这个问题,我们需要加入lambda表达式merger作为第三个参数

(value1, value2) -> new Peopel(value2.getId(), value1.getName())

当检测到有重复Key时就会用到该lambda表达式。

Map<String, People> map5 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(value1, value2) -> new People(value2.getId(), value1.getName())));
printMap("map5", map5);
/*** map5:* George:People{id=4, name='George'}* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* Henry:People{id=5, name='Henry'}*/

从结果可以看出重复的key_“Henry”将合并为一个新的键值对,id取自map2,name取自map1。_

4. Stream.of()

通过Stream.of()方法不需要借助其他stream就可以实现map的合并。

Map<String, People> map6 = Stream.of(map1, map2).flatMap(map -> map.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1, v2) -> new People(v1.getId(), v2.getName())));
printMap("map6", map6);
/*** map6:* George:People{id=4, name='George'}* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* Henry:People{id=1, name='Henry'}*/

首先将map1和map2的元素合并为同一个流,然后再转成map。通过使用v1的id和v2的name来解决重复key的问题。

5. Simple Streaming

我们还可以借助stream的管道操作来实现map合并。

Map<String, People> map7 = map2.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1, v2) -> new People(v1.getId(), v2.getName()),() -> new HashMap<>(map1)));
printMap("map7", map7);
/*** map7:* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* George:People{id=4, name='George'}* Henry:People{id=1, name='Henry'}*/

参考:

  • https://www.baeldung.com/java-merge-maps

所有代码:

package learn;import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;class People {private Long id;private String name;public People(Long id, String name) {this.id = id;this.name = name;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "People{" +"id=" + id +", name='" + name + ''' +'}';}
}public class TestMergeMap {private static Map<String, People> map1 = new HashMap<>();private static Map<String, People> map2 = new HashMap<>();static {People people1 = new People(1L, "Henry");map1.put(people1.getName(), people1);People people2 = new People(2L, "Annie");map1.put(people2.getName(), people2);People people3 = new People(3L, "John");map1.put(people3.getName(), people3);People people4 = new People(4L, "George");map2.put(people4.getName(), people4);People people5 = new People(5L, "Henry");map2.put(people5.getName(), people5);}public static void main(String[] args) {// 通过拷贝map1中的元素来构造一个新的HashMapMap<String, People> map3 = new HashMap<>(map1);// 引入merge函数和合并规则 map3.merge(key, value, (v1, v2) -> new People(v1.getId(), v2.getName())// map2进行迭代将其元素合并到map3中map2.forEach((key, value) -> map3.merge(key, value, (v1, v2) -> new People(v1.getId(), v2.getName())));printMap("map3", map3);/*** map3:* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* George:People{id=4, name='George'}* Henry:People{id=1, name='Henry'}*/try {Map<String, People> map4 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));printMap("map4", map4);} catch (IllegalStateException e) {System.out.println("Error: " + e);}Map<String, People> map5 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(value1, value2) -> new People(value2.getId(), value1.getName())));printMap("map5", map5);/*** map5:* George:People{id=4, name='George'}* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* Henry:People{id=5, name='Henry'}*/Map<String, People> map6 = Stream.of(map1, map2).flatMap(map -> map.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1, v2) -> new People(v1.getId(), v2.getName())));printMap("map6", map6);/*** map6:* George:People{id=4, name='George'}* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* Henry:People{id=1, name='Henry'}*/Map<String, People> map7 = map2.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(v1, v2) -> new People(v1.getId(), v2.getName()),() -> new HashMap<>(map1)));printMap("map7", map7);/*** map7:* John:People{id=3, name='John'}* Annie:People{id=2, name='Annie'}* George:People{id=4, name='George'}* Henry:People{id=1, name='Henry'}*/}private static void printMap(String topic, Map<String, People> map) {System.out.println(topic + ":");map.forEach((key, value) -> {System.out.println(key + ":" + value);});}
}

java-合并两个Map相关推荐

  1. java map合并_详解Java8合并两个Map中元素的正确姿势

    1. 介绍 本入门教程将介绍Java8中如何合并两个map. 更具体说来,我们将研究不同的合并方案,包括Map含有重复元素的情况. 2. 初始化 我们定义两个map实例 private static ...

  2. java 合并两个列表_如何在Java中合并两个列表?

    java 合并两个列表 Merging two lists in Java is often a useful operation. These lists can be ArrayLists or ...

  3. java using用法_如何使用java合并两个PPT。(How to merge two PPTs using java.)

    如何使用java合并两个PPT.(How to merge two PPTs using java.) 问题描述 (Problem Description) 如何使用java合并两个PPT. 解决方案 ...

  4. java:合并两个排序的整数数组A和B变成一个新的数组。新数组也要有序。

    合并两个排序的整数数组A和B变成一个新的数组.新数组也要有序. 样例 1:输入: A=[1], B=[1]输出:[1,1]样例解释: 返回合并后的数组.样例 2:输入: A=[1,2,3,4], B= ...

  5. java合并两个set_Java中合并两个集合的方法

    要在JAVA中合并两个集合,代码如下所示的− 示例import java.util.stream.*; import java.util.*; import java.io.*; public cla ...

  6. java中两个map的融合(两个map有相同字段)

    试想这样一个场景: 数据库表中 有 城市信息表 city_tbl: 有院士信息表  ys_tbl ,其中院士有城市id字段(id): 但是不是所有城市都有院士: 我们想要得到 城市的详细信息,包括院士 ...

  7. java合并两个有序链表_JS实现的合并两个有序链表算法示例

    本文实例讲述了JS实现的合并两个有序链表算法.分享给大家供大家参考,具体如下: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1-> ...

  8. java 合并两个List并去掉重复项

    工作中很多时候需要用到合并两个List并去除其中的重复内容. java8之前 在java8之前比较常规的做法是将两个List添加到一个Set中,因为Set的内容不可重复,所以会自动去重,然后再由Set ...

  9. Java合并两个List并去掉重复项的几种做法

    一.前言 工作中很多时候需要用到合并两个List并去除其中的重复内容,这是一个很简单的操作,实现的方法也多种多样,请继续往下看 二.使用stream方式进行去重(需要jdk1.8及以上) String ...

  10. Java合并两个int数组合并_Java中如何把两个数组合并为一个

    在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题.但是如何才能把代码写得高效简洁,却还是值得思考的.这里介绍四种方法,请参考选用. 一.apache-commons 这是 ...

最新文章

  1. 写给互联网产品人的进阶感言
  2. Windows下mysql忘记密码的解决方法
  3. Validate + Boostrap tooltip 表单验证示例
  4. PHP 5.4中的traits特性
  5. 共享两个有用的网页布局表格 【有用】
  6. 部分高级正则特性 使用
  7. 激光雕刻机的位图-GCode转换方法实践
  8. gmp计算机分类,GMP附录——计算机化系统汇总.pptx
  9. Blend for Visual Studio 概述
  10. [LeetCode]506. Relative Ranks
  11. Skype for Business Client 2016 聊天记录存放公共邮箱
  12. 吕布机器人评测_实情使用曝光:腾讯态客王者荣耀吕布机器人音箱怎么样?好用吗?使用七周体验分享...
  13. Linux使用445端口,利用enum4linux 445端口+wordpress插件任意文件上传的一次渗透
  14. 整理程序员常用英语单词1695个
  15. java des 中文乱码_网络上DesUtil.java关于汉字加密解密出现乱码的问题
  16. Ogre导入3Dmax模型注意事项
  17. OpenAI 推出漏洞赏金计划,最高奖励 2 万美元;京东零售开启 5 年来最大组织变革;​Django 4.2|极客头条
  18. Python数据分析初探项目 基于Python数据可视化的网易云音乐歌单分析系统 大学编程作业(TUST 天津科技大学 2022年)
  19. 精确查找top k和非精确查找top k
  20. EZ USB Suite工程导入

热门文章

  1. 香侬科技独家对话斯坦福大学计算机学院教授、麦克阿瑟天才奖得主Dan Jurafsky...
  2. Matlab特殊符号一览表
  3. java条形图_java使用jfreechart绘制条形统计图
  4. 如何在jsp内嵌音乐_JSP页面内嵌播放器的实现方法
  5. 定义全局变量的几种方式
  6. [VB.net][WinForm]Panel控件移动\鼠标拖动
  7. 【电气专业知识问答】问:高压变频器控制技术有哪几种?
  8. gulp 4.0--前端构建工具基本环境搭建及使用
  9. 2021-09-13 iMessage
  10. 智能音箱遭遇价格寒冬,技术与内容才是远航的破冰船