Grouping list of objects and reduce subgroups into different objects in Java 8

mmsr :

I have this requirement of transforming a List of Objects into List of grouped objects of different type.

public class Person {
private String name;
private String dept;
private int amount;
    //constructors
    //getters and setters
}


public class GroupedPersons {

private String dept;
private int sumAmount;
private List<Person> personsOfDept; 

    // how should be the constructor??
    //getters and setters
}  


List<Person> persons = Arrays.asList(
            new Person("Mark", "Sales", 100),
            new Person("Rob", "Marketing", 200),
            new Person("Kyle", "Sales", 150),
            new Person("Jack", "Accounts", 50),
            new Person("Sam", "Sales", 150),
            new Person("Jeff", "Marketing", 200));

I need the result as

List<GroupedPersons> 

["Sales",400,List<Person>]
["Marketing",400,List<Person>]
["Accounts",50,List<Person>]

I tried

Map<String,List<Person>> deptMap = persons.stream().collect(Collectors.groupingBy(Person::getDept));

But unable to reduce the map to the List of object I need.

Fullstack Guy :

We can use a constructor for the GroupedPersons class that will take the dept, sumAmount and personsOfDept list, like so:

class GroupedPersons {

    private String dept;
    private int sumAmount;
    private List<Person> personsOfDept;

    public GroupedPersons(String dept, int sumAmount, List<Person> personsOfDept) {
        this.dept = dept;
        this.sumAmount = sumAmount;
        this.personsOfDept = personsOfDept;
    }
}

Then we can use the the following logic to first get the grouping done by dept of the Person which will result in a Map<String, List<Person>> and then using the stream from the entrySet().stream() of the map to sum the amount and get the List<Person> from the Map.Entry<String, List<Person>>.getValue():

 List<GroupedPersons> list = persons.stream()
                                    .collect(Collectors.groupingBy(p -> p.getDept()))
                                    .entrySet()
                                    .stream()
                                    .map(ent -> new GroupedPersons(
                                                ent.getKey(),
                                  ent.getValue().stream().mapToInt(p -> p.getAmount()).sum(),
                                                ent.getValue()))
                                    .collect(Collectors.toList());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=133323&siteId=1