首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合并Map<String,List<String> Java 8流

合并Map<String,List<String> Java 8流
EN

Stack Overflow用户
提问于 2016-03-24 22:59:23
回答 6查看 29.8K关注 0票数 20

我想将两个Map与JAVA 8流合并:

代码语言:javascript
复制
Map<String, List<String>> mapGlobal = new HashMap<String, List<String>>();
Map<String, List<String>> mapAdded = new HashMap<String, List<String>>();

我试着使用这个实现:

代码语言:javascript
复制
mapGlobal = Stream.of(mapGlobal, mapAdded)
                .flatMap(m -> m.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                        Collectors.mapping(Map.Entry::getValue,        
                                           Collectors.toList())
                ));

但是,此实现只创建如下结果:

Map<String, List<Object>>

如果mapGlobal中没有包含一个键,那么它将作为一个新键添加到相应的字符串列表中。如果键在mapGlobalmapAdded中被复制,则两个值列表将合并为:A = {1, 3, 5, 7}B = {1, 2, 4, 6},然后合并为A ∪ B = {1, 2, 3, 4, 5, 6, 7}

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-03-24 23:49:45

您可以通过迭代mapAdded中的所有条目并将它们合并到mapGlobal中来做到这一点。

下面通过调用mapAdded的条目来迭代forEach(action),其中操作使用每个条目的键和值。对于每个条目,我们在mapGlobal上调用mapGlobal:如果键不存在,这要么在键k下创建条目,要么调用给定的重新映射函数(如果它们已经存在)。该函数采用合并的2个列表,在本例中,首先将其添加到TreeSet中以确保唯一和排序的元素,并将其转换回列表:

代码语言:javascript
复制
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()来创建一个流管道。但是,您需要确保使用支持mapGlobal并发性的映射,比如ConcurrentHashMap

代码语言:javascript
复制
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);
}));
票数 22
EN

Stack Overflow用户

发布于 2016-11-25 14:04:06

使用foreach超过Map可以用于合并给定的数组列表。

代码语言:javascript
复制
    public Map<String, ArrayList<String>> merge(Map<String, ArrayList<String>> map1, Map<String, ArrayList<String>> map2) {
    Map<String, ArrayList<String>> map = new HashMap<>();
    map.putAll(map1);

    map2.forEach((key , value) -> {
        //Get the value for key in map.
        ArrayList<String> list = map.get(key);
        if (list == null) {
            map.put(key,value);
        }
        else {
            //Merge two list together
            ArrayList<String> mergedValue = new ArrayList<>(value);
            mergedValue.addAll(list);
            map.put(key , mergedValue);
        }
    });
    return map;
}
票数 5
EN

Stack Overflow用户

发布于 2017-09-29 18:47:05

最初的实现并不像Map<String, List<Object>>那样创建结果,而是创建Map<String, List<List<String>>>。您需要更多的流管道来生成Map<String, List<String>>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36211405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档