Как собрать в TreeMap в потоке? - PullRequest
2 голосов
/ 10 апреля 2020

У меня есть два Collectors.groupingBy в потоке. И мне нужно собрать всю информацию для TreeMap.

Мой код:

Map<LocalDate, Map<String, List<RollingField>>> fieldMap = rollingFields.stream().collect(
    Collectors.groupingBy(
            RollingField::getDate,
            Collectors.groupingBy(fi -> fi.getMeta().getName())));

И это возвращение HashMap. Что мне нужно добавить для возврата TreeMap? Мне нужно это для сортировки по LocalDate.

1 Ответ

3 голосов
/ 10 апреля 2020

Используйте метод Speci c, который позволяет обеспечить фабрику Map через Supplier, то есть
Collectors.groupingBy(Function<..> classifier, Supplier<M> mapFactory, Collector<..> downstream), где:

  • classifier отображает элементы в ключи
  • mapFactory создает новую пустую карту (здесь вы используете () -> new TreeMap<>())
  • downstream последующее сокращение

Реализация:

Map<LocalDate, Map<String, List<RollingField>>> fieldMap = rollingFields.stream().collect(
        Collectors.groupingBy(
                RollingField::getDate,                // outer Map keys
                TreeMap::new,                         // outer Map is TreeMap
                Collectors.groupingBy(                // outer Map values
                        fi -> fi.getMeta().getName(), // inner Map keys
                        TreeMap::new,                 // inner Map is TreeMap
                        Collectors.toList()           // inner Map values (default)
                )
        ));

Не беспокойтесь, что не существует такого перегруженного метода, как Collectors.groupingBy(Function<..> classifier, Supplier<M> mapFactory) без downstream. Реализация по умолчанию downstream собирает в List, поэтому можно свободно использовать его (Collectors.toList()) из JavaDo c:

. Это дает аналогичный результат до: groupingBy(classifier, toList());

...