Skip to content

Filter distinct groups and get average of String values parsing as Integer or Double

I have a POJO like below:

@Data
class Employee {
    private int id;
    private String name;
    private String salary;
    private String departmentName;
}

And a List like below:

    List<Employee> employees = new ArrayList<>();
    Employee emp1 = new Employee(1, "Jiya Brein", "4000", "HR");
    Employee emp2 = new Employee(2, "Paul Niksui", "2000", "IT");
    Employee emp3 = new Employee(3, "Martin Theron", "5000", "HR");
    Employee emp4 = new Employee(4, "Murali Gowda", "6000", "IT");
    Employee emp5 = new Employee(5, "Jacob Arthur", "8000", "HR");
    employees.add(emp1);
    employees.add(emp2);
    employees.add(emp3);
    employees.add(emp4);
    employees.add(emp5);

Now I am trying to filter and group all the employees by department and need to get the highest spending department.

If salary is of type Double (say) I can do it like below:

        Employee emp1 = new Employee(1, "Jiya Brein", 4000d, "HR");
        Employee emp2 = new Employee(2, "Paul Niksui", 2000d, "IT");
        Employee emp3 = new Employee(3, "Martin Theron", 5000d, "HR");
        Employee emp4 = new Employee(4, "Murali Gowda", 6000d, "IT");
        Employee emp5 = new Employee(5, "Jacob Arthur", 8000d, "HR");

        Map<String, Double> avgSalaryOfDepartments = employees.stream().collect(
                Collectors.groupingBy(Employee::getDepartmentName, Collectors.averagingDouble(Employee::getSalary)));
        Set<Entry<String, Double>> entrySet = avgSalaryOfDepartments.entrySet();
        Map.Entry<String, Double> maxSpenderDept = null;
        for (Entry<String, Double> entry : entrySet) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
            if (maxSpenderDept == null || entry.getValue().compareTo(maxSpenderDept.getValue()) > 0) {
                maxSpenderDept = entry;
            }
        }
        return maxSpenderDept.toString();

And I get the expected output:

HR : 5666.666666666667
IT : 4000.0
The highest spending department is HR=5666.666666666667

But I am clueless what to do if I get the salary as String and have to parse it as Double using Java 8’s stream chaining?

Answer

You can parse it while averaging. Try using this lambda:

emp -> Double.parseDouble(emp.getSalary())

instead of this method reference:

Employee::getSalary

The full pipeline:

Map<String, Double> avgSalaryOfDepartments = 
                employees.stream()
                         .collect(groupingBy(Employee::getDepartmentName, 
                                             averagingDouble(emp -> Double.parseDouble(emp.getSalary()))));