преобразовать из карты <Object, Set <Object>> в карту <String, Set <String>> - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть карта Map<String, Set<String>>

Map<String, Set<String> result = map.entrySet().parallelStream().collect(
            Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));

Я хочу преобразовать его в Map<String, Set<String>>. сгруппировав значения и поменяв местами ключ и значение.

Но эта строка дает мне

Type mismatch: cannot convert from Map<Object,Set<Object>> to Map<String,Set<String>>

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Вот пример с учетом того, что ваша начальная Карта - это Объект-Объект.При необходимости адаптируйтесь.

Map<Object,Object> map = new HashMap<>();
Map<String, Set<String>> result = map
            .entrySet()
            .parallelStream()
            .collect(Collectors.groupingBy(entry -> (String) entry.getKey(), 
                     Collectors.mapping(entry -> (String) entry.getKey(), Collectors.toSet())));

Проблема с вашим кодом заключается в том, что Map.Entry::getKey возвращает объект, а не строку.

0 голосов
/ 18 сентября 2018

Просто чтобы избежать путаницы, я отвечаю на мой вопрос.Спасибо @AndyTurner @alexrolea за указание решения.

Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
                .collect(
                Collectors.groupingBy(entry -> (Set<String>) entry.getValue(), 
                        Collectors.mapping(entry -> entry.getKey(), Collectors.toSet())));

Мне пришлось заменить Map.Entry::getValue на entry -> (Set<String>) entry.getValue() и другой тоже.

Это помогло мне сгруппировать картупо значениям и использовать их в качестве ключей.Спасибо @ nullpointer

На самом деле, это тоже работает.Проблема в том, что я не вернул правильный тип данных.

Map<Set<String>, Set<String>> result = map.entrySet().parallelStream()
                .collect(
                Collectors.groupingBy(Map.Entry::getValue, 
                        Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));
0 голосов
/ 18 сентября 2018

Проблема, с которой вы столкнулись, это тип карты, которую вы создаете:

Map<Set<String>, Set<String>>

, а не Map<String, Set<String>>.

Таким образом, вам необходимо расширитьСначала значения карты, например:

Map<String, Set<String>> collect = map.entrySet()
    .parallelStream()
    // Expand (k, {v1, v2, v3}) to [(v1, k), (v2, k), (v3, k)]
    .flatMap(e -> e.getValue().stream().map(ee -> new SimpleEntry<>(ee, e.getKey())))
    .collect(
        Collectors.groupingBy(
            Map.Entry::getKey,
            Collectors.mapping(Map.Entry::getValue, Collectors.toSet())));

Если вы не действительно нуждаетесь в параллельной обработке, я думаю, что было бы намного проще использовать циклы:

Map<String, Set<String>> collect = new HashSet<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
  for (String v : entry.values()) {
      collect.computeIfAbsent(v -> new HashSet<>())
              .add(entry.getKey()));
  }
}
...