java-合并两个Map
2021/5/15 20:28:57
本文主要是介绍java-合并两个Map,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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; } @Override public 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中的元素来构造一个新的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'} */ 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的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南