0

Structure:

Accounting
  + Map<Employee, EmployeeCard> getEmployeeCards()

EmployeeCard
  + Map<LocalDate, Report> getReports()

Report
  + double getSalary()

I need to calculate salary sum of all reports of all employee cards.

My variant using two cycles:

public double getCostsOfEmployeesSalaries() {
  double sumOfSalary = 0;

  for (EmployeeCard card : accounting.getEmployeeCards().values()) {
    Collection<Report> reports = card.getReports().values();

    for (Report report : reports) {
      sumOfSalary += report.getSalary();
    }
  }

  return sumOfSalary;
}

Is there any solution to calculate sum using java stream API?

Jens
  • 67,715
  • 15
  • 98
  • 113
domartynov
  • 58
  • 5

2 Answers2

2

Try something like this:

public double getCostsOfEmployeesSalaries() {
    return accounting.getEmployeeCards().values().stream()
            .map(card -> card.getReports().values())
            .flatMap(Collection::stream)
            .mapToDouble(Report::getSalary)
            .sum();
}
Houari Zegai
  • 98
  • 1
  • 10
  • 2
    Or just `accounting.getEmployeeCards().values().stream() .flatMap(card -> card.getReports().values().stream()) .mapToDouble(Report::getSalary) .sum();` not splitting the flatMap step into two steps. – Holger Aug 24 '22 at 13:12
  • Good idea @Holger, is there any performance issue if we make it in two steps? – Houari Zegai Aug 24 '22 at 13:16
  • 1
    No, if there’s a difference, it’s rather negligible. – Holger Aug 24 '22 at 13:19
1

You could do it like that:

public double getCostsOfEmployeesSalaries() {
  return accounting.getEmployeeCards().values()
          .stream()
          .mapToDouble(card -> card.getReports().values()
                  .stream()
                  .mapToDouble(Report::getSalary)
                  .sum())
          .sum();
}

Map each card to a double by summing the salary from each report, then sum the resulting double stream. As noted in comments, you should not use double when working with money, but BigDecimal instead.

Personally i would use the loops instead of streams, but that's just my preference.

Chaosfire
  • 4,818
  • 4
  • 8
  • 23