Search code examples
javadatetimehashmapjava-stream

Obtain the Count per Month from the Count per Day using Java Streams and groupingBy()


I want to transform a list with per-day sales (whatever, doesn't matter) into a list of per-month sales.

So I have a List<Map<String, Object>> perDay, which contains these daily values:

[{DATE=2022-01-01, COUNT=5}, {DATE=2022-01-02, COUNT=3}, {DATE=2022-02-29, COUNT=4}]

These values should be gathered into monthly values, like that:

[{DATE=2022-01, COUNT=8}, {DATE=2022-02, COUNT=4}]

I want to use groupingBy() method with streams.

Here's my code:

    Map<String, Object> jan1 = new HashMap<>();
    jan1.put("DATE", "2022-01-01"); jan1.put("COUNT", "5");
    Map<String, Object> jan2 = new HashMap<>();
    jan2.put("DATE", "2022-01-02"); jan2.put("COUNT", "3");
    Map<String, Object> feb1 = new HashMap<>();
    feb1.put("DATE", "2022-02-29"); feb1.put("COUNT", "4");
    List<Map<String, Object>> perDay = List.of(jan1, jan2, feb1);

Map<String, Object> perMonth = perDay.stream()
        .collect(Collectors.groupingBy("???", 
                    Collectors.summingInt(f -> Integer.parseInt((String) f))));

I guess, I'm close, but I'm not quite there yet.

Any ideas?


Solution

  • assuming that your dates are always in format

    2022-01-01
    

    You could try:

     var map = perDay.stream().collect(
                      Collectors.groupingBy(monthMap -> ((String) monthMap.get("DATE")).substring(0, 7),
                      Collectors.summingInt(monthMap -> Integer.parseInt(String.valueOf(monthMap.get("COUNT"))))));
    

    Returns:

    {2022-01=8, 2022-02=4}