java

您所在的位置:网站首页 将两个列表内容合并的方法 java

java

2023-12-24 03:55| 来源: 网络整理| 查看: 265

Java8中如何合并两个map?

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

1. 初始化

我们定义两个map实例

private static Map map1 = new HashMap(); private static Map 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 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 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 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 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 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 map1 = new HashMap(); private static Map 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 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 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 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 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 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 map) { System.out.println(topic + ":"); map.forEach((key, value) -> { System.out.println(key + ":" + value); }); } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3