您能帮我合并几张地图的值吗?

时间:2018-11-05 12:41:21

标签: java java-8 hashmap java-stream collectors

我正在尝试进行以下修改:

final Map<String, List<Map<String, String>>> scopes = scopeService.fetchAndCacheScopesDetails();
final Map<String, Map<String, String>> scopesResponse = scopes.entrySet().stream().collect
        (Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
                .stream().collect(Collectors.toMap(s -> (String) s.get(SCOPE_NM), s -> (String) s.get(SCOPE_ID))))
        );

但是我遇到了"Duplicate key"错误,因此我想将scopeResponses更改为Map<String, Map<String, List<String>>>

您能告诉我在这种情况下如何将值s -> (String) s.get(SCOPE_ID)合并到ListSet中吗?

2 个答案:

答案 0 :(得分:5)

您需要为内部Set的值创建一个Map,并提供合并功能:

final Map<String, Map<String, Set<String>>> scopesResponse = scopes.entrySet().stream().collect
    (Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
            .stream().collect(Collectors.toMap(s -> s.get(SCOPE_NM),
                                               s -> {Set<String> set= new HashSet<>(); set.add(s.get(SCOPE_ID)); return set;},
                                               (s1,s2)->{s1.addAll(s2);return s1;}))));

或者,您可以使用Map构造内部groupingBy

final Map<String, Map<String, Set<String>>> scopesResponse2 = scopes.entrySet().stream().collect
    (Collectors.toMap(Map.Entry::getKey, e -> e.getValue()
            .stream().collect(Collectors.groupingBy(s -> s.get(SCOPE_NM),
                                               Collectors.mapping(s -> s.get(SCOPE_ID),Collectors.toSet())))));

答案 1 :(得分:0)

您也可以使用GuavaListMultimap(多图就像一个列表图)来做到这一点:

Map<String, ListMultimap<String, String>> scopesResponse = scopes.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, e -> toMultimap(e)));

其中

static ImmutableListMultimap<String, String> toMultimap(
        Map.Entry<String, List<Map<String, String>>> entry) {
    return entry.getValue().stream().collect(ImmutableListMultimap.toImmutableListMultimap(
            s -> (String) s.get(SCOPE_NM),
            s -> (String) s.get(SCOPE_ID)
    ));
}

如果列表中的值被证明是重复的,而您又不想这么做,请使用SetMultimap