Как использовать Collectors.groupingBy для получения значений хэш-карты

#java #java-stream

Вопрос:

Я недавно начал изучать потоки и лямбда-выражения и столкнулся с проблемой с моим кодом.

У меня есть список имен, которые я хочу сгруппировать по их длине и количеству, для которых мне пришлось дважды использовать Collectors.groupingBy ().:

 public class StreamApplicationDemo {
    public static void main(String[] args) {

        List<String> names = new ArrayList<>
              (Arrays.asList("Amir", "Hatef","Mehran", "Mojtaba",
                    "Mohammad", "Ali", "Davood", "Reza", "Mohsen"));


        Map<Integer, List<String>> groupByLengthMap = names.
            stream().
                collect(Collectors.groupingBy(name -> name.length()));
        System.out.println(groupByLengthMap);


        Map<Integer, Long> groupByLengthNumberMap = names.
                  stream().
                  collect(Collectors.groupingBy(name -> name.length(), 
        Collectors.counting()));
              System.out.println(groupByLengthNumberMap);


    }
}
 

Выход:

  {3=[Ali], 4=[Amir, Reza], 5=[Hatef], 6=[Mehran, Davood, Mohsen], 7=[Mojtaba], 8= 
 [Mohammad]}
 {3=1, 4=2, 5=1, 6=3, 7=1, 8=1}
 

Как вы можете видеть, я использовал метод терминала потоков (Сбор ()), чтобы сгруппировать список имен по их длине, а затем мне пришлось сгруппировать список в другой раз и сопоставить его по длине имен и их номерам.
Но я хочу объединить эти две группы и сделать вот так:

{3{1 = [Али]}, 4{2=[Амир, Реза]}…}

И, как вы можете видеть, я хочу иметь карту, на которой длина слов указана в качестве ключа, а также карту количества слов и их список в качестве значения этого ключа:

Карта<Целое число, Карта<Целое число, Список><Целое число, Список>>

Но я не знаю, как я могу это сделать, только используя метод Collect() и groupingBy (), который использует функцию в качестве входных данных. Возможно ли это вообще? Заранее спасибо.

Комментарии:

1. {3{1 = [Али]}, 4{2=[Амир, Реза]}…} Разве это не плохой дизайн? List есть size метод, так что он просто избыточен. С какой целью?

Ответ №1:

Попробуй это.

 public static void main(String[] args) {
    List<String> names = List.of("Amir", "Hatef", "Mehran", "Mojtaba",
        "Mohammad", "Ali", "Davood", "Reza", "Mohsen");
    Map<Integer, Map<Integer, List<String>>> result = names.stream()
        .collect(Collectors.groupingBy(String::length))
        .entrySet().stream()
        .collect(Collectors.toMap(Entry::getKey,
            e -> Map.of(e.getValue().size(), e.getValue())));
    System.out.println(result);
}
 

выход:

 {3={1=[Ali]}, 4={2=[Amir, Reza]}, 5={1=[Hatef]}, 6={3=[Mehran, Davood, Mohsen]}, 7={1=[Mojtaba]}, 8={1=[Mohammad]}}