Collectors.groupby для карты - PullRequest
       57

Collectors.groupby для карты

0 голосов
/ 31 декабря 2018

Простите, если решение очень очевидно, но я не могу понять, как это сделать

public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("b1", "a1");
    map.put("b2", "a2");
    map.put("b3", "a1");
    Map<String, List<String>> mm = map.values().stream().collect(Collectors.groupingBy(m -> m));
    System.out.println(mm);
}

Я хочу сгруппировать по значениям в hashmap.Я хочу, чтобы вывод был {a1=[b1, b3], a2=[b2]}, но в настоящее время он будет иметь вид {a1=[a1, a1], a2=[a2]}

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Вы можете использовать Collectors.mapping с Collectors.groupingBy на entrySet карты как:

Map<String, List<String>> mm = map.entrySet()
        .stream()
        .collect(Collectors.groupingBy(Map.Entry::getValue, 
                Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

, но этов настоящее время появляется как {a1 = [a1, a1], a2 = [a2]}

Это потому, что вы в настоящее время группируете коллекцию значений, которая состоит только из {a1, a2, a1}.

0 голосов
/ 31 декабря 2018

В настоящее время вы передвигаетесь по значениям карты (я предполагаю, что это опечатка), исходя из требуемого результата, вы должны передавать по карте entrySet и использовать groupingBy на основе значений карты и mappingв качестве нижестоящего коллектора на основе ключей карты:

 Map<String, List<String>> result = map.entrySet()
            .stream()
            .collect(Collectors.groupingBy(Map.Entry::getValue,
                          Collectors.mapping(Map.Entry::getKey, 
                                        Collectors.toList())));

Вы также можете выполнить эту логику без потока через forEach + computeIfAbsent:

Map<String, List<String>> result = new HashMap<>();
map.forEach((k, v) -> result.computeIfAbsent(v, x -> new ArrayList<>()).add(k));
...