I have a list of summary rows, which has few-rows-per-entity, where some scalar properties of the entity are repeated and there are two additional columns GroupName and GroupCount which are unique.
Basically this is the output of a SQL join, and the entity data is repeated and there is a unique group name, and its count in each row.
I want to stream this and collect it into an entity Dto which has the entity properties as well as a Map for the merged group statistics.
I tried an implementation using Collectors.groupingBy, but it still doesn't look right.
@Data @AllArgsConstructor public static class DepartmentSummaryRow{ private int id; private String name; private String groupName; private int groupMembersCount; } @Data @AllArgsConstructor public static class Department{ private int id; private String name; @EqualsAndHashCode.Exclude private final Map<String, Integer> groupCounts = new HashMap<>(); } public static void main(String[] args) { grouping(); } private static void grouping() { Gson g = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); //Test data List<DepartmentSummaryRow> summaries = new ArrayList<>(); for(int i=1;i<=50;i++) { summaries.add( new DepartmentSummaryRow(i, "name_a"+i, "g1", 3 ) ); summaries.add( new DepartmentSummaryRow(i, "name_b"+i, "g2", 9 ) ); } //Just group the summary rows Map<Department, List<DepartmentSummaryRow>> departmentsToSummaries = summaries .stream() .collect( Collectors.groupingBy( (summary)->{ return new Department(summary.id, summary.name); }, LinkedHashMap::new, Collectors.toList() ) ); //Merge the info into the departments departmentsToSummaries.forEach( (entity, sumaryRow)->{ entity.groupCounts.putAll( sumaryRow.stream().collect( Collectors.groupingBy( DepartmentSummaryRow::getGroupName, Collectors.summingInt( DepartmentSummaryRow::getGroupMembersCount ) ) ) ) ; } ); System.out.println( g.toJson( departmentsToSummaries.keySet() ) ); } I am looking for some ideas for a better implementation than this for grouping a stream into custom POJOs. Any suggestions would be helpful. Thanks!
(Note: this itself has some bug.. for some reason the first grouping by my POJO doesn't group at all.. which is odd, as it has a good hashcode and equals provided by Lombok)
Edit: Here's what the input looks like:
[ { "id": 1, "name": "name_a1", "groupName": "g1", "groupMembersCount": 3 }, { "id": 1, "name": "name_b1", "groupName": "g2", "groupMembersCount": 9 }, { "id": 2, "name": "name_a1", "groupName": "g1", "groupMembersCount": 3 }, ... ] And here's the expected result:
[ { "id": 1, "name": "name_a1", "groupCounts": { "g1": 3, "g2": 9 } }, { "id": 2, "name": "name_a2", "groupCounts": { "g1": 3, "g2": 9 } }, ... ]