# [SOLVED] Find the sum of values of an Employee and its Parent using stream

## Issue

Consider, I have the following class.

``````public class Employee {

private Integer id;
private Integer parentId;
private int value;
}
``````

Now I have the following records.

``````    Employee employee1 = new Employee(1, null, 4);
Employee employee2 = new Employee(2, 1, 4);
Employee employee3 = new Employee(3, null, 8);
Employee employee4 = new Employee(4, 1, 3);
Employee employee5 = new Employee(5, 2, 11);
``````

So the `parentId` is the `id` of an employee who is the boss of another employee.

The question is to find out the sum of the value of an employee and it’s parent if it has any, or return the value as it is. So in this case, the result should be.

id value
1 4
2 8
3 8
4 7
5 15

How to achieve this using java 8 streams? I have tried the following;

``````  Optional<Integer> first = employees.stream().map(a -> {
int sum = 0;
employees.stream().map(b -> {
if (Objects.equals(a.id, b.parentId)) {
sum = sum + a.value + b.value;
}else{
sum  = sum + a.value;
}
return sum;
});
return sum;
}
).findFirst();
``````

But I am getting error with the sum variable that it should be final or effectively final.

## Solution

The most efficient way to achieve that is to create a map which will allow to retrieve the `value` of an `Employee` by its `id`.

Then, in order to combine the `value` of each `Employee` with its parent’s `value`, use the value from the map or `0` if the parent is `null`.

Method below generates a map with `id` used as a key and employee’s `value` as a value.

``````public static Map<Integer, Integer> getEmplValueById(List<Employee> employees) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
Employee::getValue));
}
``````

The following method creates a map with `id` used as a key and the total value of an employee as a map’s value.

``````public static Map<Integer, Integer> getEmplSumById(List<Employee> employees,
Map<Integer, Integer> valueById) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
empl -> empl.getValue() +
valueById.getOrDefault(empl.getParentId(), 0)));
}
``````

`main()`

``````public static void main(String[] args) {
List<Employee> employees = List.of(
new Employee(1, null, 4),
new Employee(2, 1, 4),
new Employee(3, null, 8),
new Employee(4, 1, 3),
new Employee(5, 2, 11));

Map<Integer, Integer> valueById = getEmplValueById(employees);

getEmplSumById(employees, valueById)
.forEach((k, v) -> System.out.printf("ID %d \t value %d\n", k, v));
}
``````

Output

``````ID 1     value 4
ID 2     value 8
ID 3     value 8
ID 4     value 7
ID 5     value 15
``````