合并映射< String,List< String> Java 8流 [英] Merge Map<String, List<String> Java 8 Stream
问题描述
我想将两个Map与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 groupingBy(Map.Entry :: getKey,
Collectors.mapping(Map.Entry :: getValue,
Collectors.toList())
));
但是,此实现只创建一个结果:
$ b b
地图< String,List< Object>>
如果一个键不包含在 mapGlobal
,它将作为一个新的键与相应的字符串列表一起添加。如果键在 mapGlobal
和 mapAdded
中重复,则两个值列表将合并为: A = {1,3,5,7}
和 B = {1,2,4,6}
然后 A∪B = {1,2,3,4,5,6,7}
。
您可以通过迭代 mapAdded
中的所有条目并将它们合并到 mapGlobal
中来实现。 >
下面通过调用 mapAdded javas / 8 / docs / api / java / util / Map.html#forEach-java.util.function.BiConsumer-rel =nofollow> forEach(action)
,其中操作使用每个条目的键和值。对于每个条目,我们调用 mapGlobal 上的rel =nofollow> merge(key,value,remappingFunction)
:如果键不存在或者它将调用给定的重新映射,则在键 k
下创建条目并且键 v
如果它们已经存在。此函数采用2个列表进行合并,在这种情况下,首先将其添加到 TreeSet
,以确保唯一的和排序的元素并转换回列表:
mapAdded.forEach((k,v) - > mapGlobal.merge(k,v,(v1,v2)
Set< String> set = new TreeSet<>(v1);
set.addAll(v2);
return new ArrayList(set);
} );
如果你想并行运行,你可以创建一个流管道, c $ c> entrySet()并调用 parallelStream()
。但是,您需要确保使用支持 mapGlobal
的并发性的映射,如 ConcurrentHashMap
。
ConcurrentMap< String,List< String> mapGlobal = new ConcurrentHashMap<>();
// ...
mapAdded.entrySet()。parallelStream()。forEach(e - > mapGlobal.merge(e.getKey(),e.getValue(),(v1,v2) - > {
Set<> set = new TreeSet<>(v1);
set.addAll(v2);
return new ArrayList& $ b}));
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>>();
I try to use this implementation:
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:
Map<String, List<Object>>
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}
.
You can do this by iterating over all the entries in mapAdded
and merging them into mapGlobal
.
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);
}));
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);
}));
这篇关于合并映射< String,List< String> Java 8流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!