Home > Software design >  Java streams Map<String,List<Object>> Convert each item to dto by the date (only month)
Java streams Map<String,List<Object>> Convert each item to dto by the date (only month)

Time:11-20

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)
  • Related