MMSR:
Tengo este requisito de transformar una lista de objetos en la lista de objetos agrupados de diferente tipo.
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));
Necesito el resultado como
List<GroupedPersons>
["Sales",400,List<Person>]
["Marketing",400,List<Person>]
["Accounts",50,List<Person>]
Lo intenté
Map<String,List<Person>> deptMap = persons.stream().collect(Collectors.groupingBy(Person::getDept));
Pero incapaz de reducir el mapa a la lista de objetos que necesito.
Gracias completo Guy:
Podemos utilizar un constructor de la GroupedPersons
clase que se llevará a la dept
, sumAmount
y la personsOfDept
lista, así:
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;
}
}
Entonces podemos usar el la siguiente lógica para obtener por primera vez la agrupación hecho por dept
el Person
que se traducirá en una Map<String, List<Person>>
y luego usando la corriente de la entrySet().stream()
del mapa para resumir el amount
y obtener el List<Person>
de la 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());