Reputation: 12744
I have a list of sorted dates like this:
2016-07-07
2016-07-08
2016-07-09
2016-07-10
2016-07-11
2016-07-12
2016-07-13
...
2016-07-31
2016-08-01
2016-08-02
2016-08-03
...
2017-01-01
2017-01-02
2017-01-03
...
From this list I generate a Map<YearMonth, List<LocalDate>>
with stream:
Map<YearMonth, List<LocalDate>> d = dates.stream().collect(Collectors.toList())
.stream().collect(Collectors.groupingBy(date -> YearMonth.from(date)));
The output of that map looks like this:
{2016-12=[2016-12-01, 2016-12-02,...2016-12-31], 2016-11=[2016-11-01, 2016-11-02,...]}
But my needed output should look be like this:
{2016-07=[...], 2016-08=[...]}
{2016-07=[2016-07-01, 2016-07-02, ...], 2016-08=[2016-08-01, 2016-08-02, ...]}
I tried many options to get my expected result but I just get the correct sorting for the key or the value and not for both:
Map<YearMonth, List<LocalDate>> m = stream().collect(Collectors.toList())
.stream().sorted((e1,e2) -> e2.compareTo(e1))
.collect(Collectors.groupingBy(date -> YearMonth.from(date)));
Result:
{2016-07=[2016-07-31, 2016-07-30, ...], 2016-08=[2016-08-31, 2016-08-30, ...]}
How can I sort both by key and value?
Upvotes: 3
Views: 4294
Reputation: 5558
Use a TreeMap as collector so the output is sorted by key.
Something like this:
dates.stream()
.sorted()
.collect(
Collectors.groupingBy(YearMonth::from, TreeMap::new, Collectors.toList())
);
Upvotes: 4
Reputation: 41
You can sort them in the following way:-
Map<YearMonth, List<LocalDate>> map = dates.stream()
.collect(Collectors.toList())
.stream()
.sorted((e1,e2) -> e1.compareTo(e2))
.collect(Collectors.groupingBy(date -> YearMonth.from(date), TreeMap::new, Collectors.toList()));
Upvotes: 0
Reputation: 6200
You can use specific Collectors
that return a sorted Collection.
In your case I would use a TreeMap
to sort the resulting Map by its keys, and explicitly sort the resulting value collections like that:
Map<YearMonth, List<LocalDate>> m = dates.stream()
.collect(Collectors.groupingBy(
date -> YearMonth.from(date),
TreeMap::new,
Collectors.collectingAndThen(
Collectors.toList(),
(list) -> { Collections.sort(list); return list; })));
Upvotes: 1
Reputation: 439
Collectors.groupingBy(date -> YearMonth.from(date))
internally stores result in HashMap and key sorting is lost.
This implementation will preserve keys order:
Map<YearMonth, List<LocalDate>> d = dates
.stream()
.sorted((e1,e2) -> e2.compareTo(e1))
.collect(Collectors
.groupingBy(YearMonth::from,
LinkedHashMap::new,
Collectors.toList()));
Upvotes: 3