How to collect into TreeMap in stream?

Viewed 703

I have two Collectors.groupingBy in Stream. And I need to collect all information to TreeMap.

My Code:

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

And this return HashMap. What i need to add for returning TreeMap? I need this for sorting by LocalDate.

1 Answers

Use the specific method that allows to provide a Map factory through Supplier that is
Collectors.groupingBy(Function<..> classifier, Supplier<M> mapFactory, Collector<..> downstream) where:

  • classifier maps elements into keys
  • mapFactory produces a new empty map (here you use () -> new TreeMap<>())
  • downstream the downstream reduction

Implementation:

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)
                )
        ));

Don't worry that there is no such overloaded method like Collectors.groupingBy(Function<..> classifier, Supplier<M> mapFactory) without downstream. The default implementation of downstream is collecting to List, therefore free to reuse it (Collectors.toList()), from the JavaDoc:

This produces a result similar to: groupingBy(classifier, toList());

Related