Of course, you can sort the entire stream before collecting:
Map<String, List<String>> beansByDomain = beans.stream() .map(ObjectInstance::getObjectName) .sorted(Comparator.comparing(ObjectName::getCanonicalKeyPropertyListString)) .collect(groupingBy(ObjectName::getDomain, mapping(ObjectName::getCanonicalKeyPropertyListString, toList() )));
Note that I added the .map(ObjectInstance::getObjectName) step .map(ObjectInstance::getObjectName) , since you don't need anything else from ObjectInstance . This will work well, although I cannot predict whether it will be faster than sorting each resulting list separately or not.
If you prefer a separate toSortingList() collector (as in @JeanLogeart's answer), it can be optimized as follows:
public static <T extends Comparable<T>> Collector<T,?,List<T>> toSortedList() { return collectingAndThen(toCollection(ArrayList::new), (List<T> l) -> {l.sort(Comparator.naturalOrder()); return l;}); }
Here we explicitly collect for ArrayList ( toList() does the same, but this is not guaranteed), then sort the resulting list in place without additional copying (using stream().sorted().collect(toList()) , you copy the contents the entire list at least twice). Also note that the <T> parameter must be declared as extends Comparable<T> . Otherwise, you may mistakenly use this collector for a disparate type that will compile fine, but will result in a runtime error.
Tagir valeev
source share