I am new to Java 8, and have had trouble implementing already provided solution here on a similar kind of issue. Please help.
In Java 8 group by how to group by on three fields which returns more than one row that has to sum up on the rest of two Integer fields. Here in the below dto/pojo class need to make a sum up of incomingCount and outgoingCount fields based on the unique key of uuid, msgDate, and channel combined.
public class ReportData {
private String uuid;
private String msgDate;
private String channel;
private Integer incomingCount;
private Integer outgoingCount;
}
//Initializing List as sample.
List<ReportData> list1 = new ArrayList<>();
list1.add(new ReportData("c9c3a519","December 2023", "digital", 5, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "digital", 3, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "digital", 0, 3 ));
list1.add(new ReportData("c9c3a519","November 2023", "digital", 4, 0 ));
list1.add(new ReportData("c9c3a519","November 2023", "digital", 0, 4 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 5, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 3, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 0, 3 ));
list1.add(new ReportData("c9c3a519","November 2023", "manual", 4, 0 ));
list1.add(new ReportData("c9c3a519","November 2023", "manual", 0, 4 ));
list1.add(new ReportData("3de4c44f","December 2023", "digital", 5, 0 ));
list1.add(new ReportData("3de4c44f","December 2023", "digital", 0, 3 ));
list1.add(new ReportData("3de4c44f","November 2023", "digital", 4, 0 ));
list1.add(new ReportData("3de4c44f","November 2023", "digital", 0, 4 ));
list1.add(new ReportData("3de4c44f","December 2023", "manual", 5, 0 ));
list1.add(new ReportData("3de4c44f","December 2023", "manual", 0, 3 ));
list1.add(new ReportData("3de4c44f","November 2023", "manual", 4, 0 ));
list1.add(new ReportData("3de4c44f","November 2023", "manual", 0, 4 ));
Output Object should have data as below:
uuid msgDate channel incomingCount outgoingCount
c9c3a519 December 2023 digital 8 3
c9c3a519 November 2023 digital 4 4
c9c3a519 December 2023 manual 8 3
c9c3a519 November 2023 manual 4 4
...
...
...
Collect the result into a Map. This example will use Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapFactory).
Also I am using lombok annotations for brevity.
First start by creating classes to represent the keys you want to group by and the aggregated data:
Then extend
ReportDatawith 2 more methods to create the key and initial aggregation:And collect the data:
The arguments of the Collector are as follows:
ReportData::createKey- creates the key to group by (key of the map)ReportData::createCount- creates the initial aggregation from a singleReportData(value of the map)Count::merge- merges twoCounts on key collision (see the merge method)LinkedHashMap::new- factory for aMapto insert the results in. I want to preserve insertion order, but if you don't need to, you can just omit the parameter to use the default factory.Prints: