Инвертировать карту со значением списка Map <Key, List <Value>> to Map <Value, Key> в Java 8 - PullRequest
0 голосов
/ 09 января 2019

У меня есть вид карт группировки значений по ключу Map<String, List<Integer>>, я хочу вернуться, чтобы сопоставить каждое значение с соответствующим ключом

Пример: я хочу преобразовать код ниже

Map<String, List<Integer>> mapOfIntList = new HashMap<String, List<Integer>>();

mapOfIntList.put("UNIT", Arrays.asList(1, 2, 3, 8, 7, 0, 8, 6));
mapOfIntList.put("TEN", Arrays.asList(24, 90, 63, 87));
mapOfIntList.put("HUNDRED", Arrays.asList(645, 457, 306, 762));
mapOfIntList.put("THOUSAND", Arrays.asList(1234, 3456, 5340, 9876));

на другую карту (целое число, строка), где я могу найти: (1, "UNIT"), (2, "UNIT") ... (24, "TEN"), (90, "TEN") ... ... (645, "СТО") ... (3456, " ТЫСЯЧА ") ...

Ответы [ 4 ]

0 голосов
/ 09 января 2019

Вы можете использовать

Map<Integer, String> mapNumberToType = mapOfIntList.entrySet().stream()
    .collect(HashMap::new, (m,e)->e.getValue().forEach(v->m.put(v,e.getKey())), Map::putAll);

Вы можете распознать сходство с кодом forEach на основе *1004* этого ответа во второй функции, переданной функции collect (аккумулятору). Для последовательного выполнения они делают в основном то же самое, но это потоковое решение поддерживает параллельную обработку. Вот почему ему нужны две другие функции: поддержка создания локальных контейнеров и их слияние.

См. Также раздел Изменчивое сокращение документации.

0 голосов
/ 09 января 2019

Это было бы проще как:

 source.entrySet()
       .stream()
       .flatMap(e -> e.getValue().stream().map(s -> new AbstractMap.SimpleEntry<>(s, e.getKey())))
       .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (l, r) -> l));
0 голосов
/ 09 января 2019

Или используйте два вложенных forEach

mapOfIntList.forEach((key, value) ->
            value.forEach(v -> {
                mapNumberToType.put(v, key);
            })
 );

как @nullpointer прокомментировал в одной строке

mapOfIntList.forEach((key, value) -> value.forEach(v -> mapNumberToType.put(v, key)));
0 голосов
/ 09 января 2019

Я нашел решение:

Map<Integer, String> mapNumberToType = mapOfIntList
    .entrySet()
    .stream()
    .flatMap(
            entry -> entry.getValue().stream()
                    .map(number -> Pair.of(number, entry.getKey()))
                    .collect(Collectors.toList()).stream())
    .collect(
            Collectors.toMap(Pair::getLeft,
                    Pair::getRight, (a, b) -> {
                        return a;
                    }));

System.out.println("Number/Type correspondance : " + mapNumberToType);

надеюсь, это поможет любому, у кого возникла такая же проблема!

...