Search code examples
javajava-streamtreemap

How to collect into TreeMap in stream?


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.


Solution

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