Problem:
I have a
Map<LocalDate, Integer>
and I want to group these map elements by week usingLocalDate
and find the max value of each grouped values by week using Java 8 Stream.I am currently having issues where I can't convert the Key back into
LocalDate
object in the stream due to the fact that I do not have the required data fields to create object ofLocalDate
into the Map.If I were to not convert this to
LocalDate
and keep it asString
instead, I cant use theTreeMap
to arrange the keys-values in natural order using the keys.If I do not include month into
DateTimeFormatter.ofPattern
when grouping the data, weeks may overlap between two years.If I only use week number Integer as output of the map from the stream, the grouped values by week will be mixed and overlapped with week numbers from another year, i.e. 2020-2021 with Week 1.
Question:
- How do I get the max value of values per week using java streams?
DataSet:
Map<LocalDate,Integer> CumulativeGarbageWasteDate = new HashMap<LocalDate,Integer>();
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2020"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("12/24/20"),DateTimeFormatter.ofPattern("M/d/yy")),140);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/20"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/1/21"),DateTimeFormatter.ofPattern("M/d/yy")),182);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/2/21"),DateTimeFormatter.ofPattern("M/d/yy")),203);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),321);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),421);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2021"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/6/21"),DateTimeFormatter.ofPattern("M/d/yy")),1200);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/31/21"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
Code:
private static Map<LocalDate, Integer> sumByWeek (Map<LocalDate,Integer> CumulativeGarbageWasteDate){
DateTimeFormatter formatter3 = new DateTimeFormatterBuilder().appendPattern("w/M/YY").parseDefaulting(ChronoField.DAY_OF_WEEK,DayOfWeek.FRIDAY.getValue()).toFormatter();
return CumulativeGarbageWasteDate
.entrySet()
.stream()
.collect(Collectors.groupingBy(
row-> LocalDate.parse(row.getKey().format(DateTimeFormatter.ofPattern("w/M/YY")),formatter3),
TreeMap::new,
Collectors.reducing(0, x->x.getValue(),Math::max)));
}
Error:
Here is the error I encountered when running the code.
java.time.format.DateTimeParseException: Text '5/2/20' could not be parsed: Conflict found: Field MonthOfYear 1 differs from MonthOfYear 2 derived from 2020-01-31