My aim is to calculate the total count of people and salary according to the month of the data time.
I stored the date as a local date.
I can also get the month value as an int variable from localtime shown below.
LocalDate localDate = ...
int month = localDate.getMonthValue();
Here is the list Map<String(pId),List (Person Object)> shown below
ID,Info,Salart,Date (All values are stored in the Person object defined in the List)
per1, SALARY, 4000, 10-01-2022
per2, SALARY, 4000, 10-01-2022
per1, SALARY, 4000, 10-02-2022
per2, SALARY, 4000, 10-03-2022
What I really want to get this result is shown below.
Month,Total Salary, Personal Count
1 8000 2
2 4000 1
3 4000 1
Here is my dto class shown below.
public class ReportDto {
private int month;
private BigDecimal totalSalary;
private int totalEmployees;
}
Here is my code snippet is shown below but I cannot have any idea how to get month value from the date during the stream process and calculate the sum of persons and salaries.
List<ReportDto> result = persons.values().stream()
.flatMap(List::stream)
...
How can I do that?
CodePudding user response:
First of all group by month, and then create a Report object from the result of the grouping, for example:
List<ReportDto> group = persons.values().stream()
.flatMap(List::stream)
.collect(Collectors.groupingBy(p -> p.getDate().getMonthValue()))
.entrySet().stream()
.map(this::toReport)
.collect(Collectors.toList());
private ReportDto toReport(Map.Entry<Integer, List<Person>> entry) {
ReportDto report = new ReportDto();
report.setMonth(entry.getKey());
report.setTotalEmployees(entry.getValue().size());
BigDecimal totalSalary = entry.getValue().stream()
.map(Person::getSalary)
.reduce(BigDecimal.ZERO, BigDecimal::add);
report.setTotalSalary(totalSalary);
return report;
}
Outputs
ReportDto(month=1, totalSalary=8000, totalEmployees=2)
ReportDto(month=2, totalSalary=4000, totalEmployees=1)
ReportDto(month=3, totalSalary=4000, totalEmployees=1)