Не могли бы вы помочь мне объединить значения нескольких карт? - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь сделать следующую модификацию:

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) в List или Set в этой ситуации?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Вы также можете сделать это, используя Гуава х ListMultimap (мультикарта похожа на карту списков):

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.

0 голосов
/ 05 ноября 2018

Вам необходимо создать 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())))));
...