Merge Maplt;String, Listlt;Stringgt; Java 8 Stream(合并映射lt;字符串、列表lt;字符串gt;Java 8 流)
问题描述
我想将两个 Map 与 JAVA 8 Stream 合并:
I would like to merge two Map with JAVA 8 Stream:
Map<String, List<String>> mapGlobal = new HashMap<String, List<String>>();
Map<String, List<String>> mapAdded = new HashMap<String, List<String>>();
我尝试使用这个实现:
mapGlobal = Stream.of(mapGlobal, mapAdded)
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())
));
然而,这个实现只创建了一个类似的结果:
However, this implementation only create a result like:
地图<字符串、列表<对象>>
如果 mapGlobal
中不包含某个键,则将其添加为具有相应字符串列表的新键.如果键在 mapGlobal
和 mapAdded
中重复,则两个值列表将合并为:A = {1, 3, 5, 7}
和 B = {1, 2, 4, 6}
然后 A ∪ B = {1, 2, 3, 4, 5, 6, 7}
..p>
If one key is not contained in the mapGlobal
, it would be added as a new key with the corresponding List of String. If the key is duplicated in mapGlobal
and mapAdded
, both list of values will be merge as: A = {1, 3, 5, 7}
and B = {1, 2, 4, 6}
then A ∪ B = {1, 2, 3, 4, 5, 6, 7}
.
推荐答案
您可以通过遍历 mapAdded
中的所有条目并将它们合并到 mapGlobal
中来做到这一点.
You can do this by iterating over all the entries in mapAdded
and merging them into mapGlobal
.
以下通过调用 mapAdded 的条目#forEach-java.util.function.BiConsumer-" rel="noreferrer">forEach(action)
其中操作使用每个条目的键和值.对于每个条目,我们调用 merge(key, value, remappingFunction)
on mapGlobal
:这将在 k
键下创建条目code> 和值 v
如果键不存在,或者如果它们已经存在,它将调用给定的重新映射函数.此函数需要合并 2 个列表,在这种情况下,首先将其添加到 TreeSet
以确保唯一且已排序的元素并转换回列表:
The following iterates over the entries of mapAdded
by calling forEach(action)
where the action consumes the key and value of each entry. For each entry, we call merge(key, value, remappingFunction)
on mapGlobal
: this will either create the entry under the key k
and value v
if the key didn't exist or it will invoke the given remapping function if they already existed. This function takes the 2 lists to merge, which in this case, are first added to a TreeSet
to ensure both unique and sorted elements and converted back into a list:
mapAdded.forEach((k, v) -> mapGlobal.merge(k, v, (v1, v2) -> {
Set<String> set = new TreeSet<>(v1);
set.addAll(v2);
return new ArrayList<>(set);
}));
如果您想潜在地并行运行,您可以通过获取 entrySet()
并在其上调用 parallelStream()
来创建 Stream 管道.但是,您需要确保为 mapGlobal
使用支持并发的映射,例如 ConcurrentHashMap
.
If you want to run that potentially in parallel, you can create a Stream pipeline by getting the entrySet()
and calling parallelStream()
on it. But then, you need to make sure to use a map that supports concurrency for mapGlobal
, like a ConcurrentHashMap
.
ConcurrentMap<String, List<String>> mapGlobal = new ConcurrentHashMap<>();
// ...
mapAdded.entrySet().parallelStream().forEach(e -> mapGlobal.merge(e.getKey(), e.getValue(), (v1, v2) -> {
Set<String> set = new TreeSet<>(v1);
set.addAll(v2);
return new ArrayList<>(set);
}));
这篇关于合并映射<字符串、列表<字符串>Java 8 流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:合并映射<字符串、列表<字符串>Java 8 流
基础教程推荐
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01