Problem:
I have a
Map<LocalDate, Integer>and I want to group these map elements by week usingLocalDateand 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
LocalDateobject in the stream due to the fact that I do not have the required data fields to create object ofLocalDateinto the Map.If I were to not convert this to
LocalDateand keep it asStringinstead, I cant use theTreeMapto arrange the keys-values in natural order using the keys.If I do not include month into
DateTimeFormatter.ofPatternwhen 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