0

I have the below requirement which might be simple but as a beginner I would like to take help here.

class Employee{
  String department;
  int age;
  int salary;
}

class Foo{
  double averagingAge;
  double averagingSalary;
}

I want to have a group by department using groupingBy(department, collector(Foo)). Can anyone help?

Naman
  • 27,789
  • 26
  • 218
  • 353
avr
  • 1
  • 1
  • 4
  • 1
    you are looking for a custom collector.. as suggested in [this answer](https://stackoverflow.com/a/27932080/1746118), you can take a look at the implementation from JDK if that helps. – Naman Jun 19 '20 at 05:48
  • @avr looks like homework. Maybe here you will get some directions: https://www.baeldung.com/java-groupingby-collector – Semo Jun 19 '20 at 06:45
  • You can do average separately for age and salary then merge them. – Eklavya Jun 19 '20 at 06:46
  • @Semo: the critical part here is to get more than one column as the result of average of each column in FOO. If you know the answer can you please post the it? – avr Jun 21 '20 at 13:18
  • @ Naman: I m trying custom collector as last option in case if I don't find any compact way of doing it. – avr Jun 21 '20 at 13:20

1 Answers1

0
custom collector is the solution in java8: 

class Foo{
  private double ageSum;
  private double salarySum;
  private long ageCount;
  private long salaryCount;

    public double getAgeAvg(){
        return ageCount != 0 ? ageSum/ageCount : 0.0;
    }

    public double getSalaryAvg(){
        return salaryCount != 0 ? salarySum/salaryCount : 0.0;
    }
}

custom collector:

Map<Department, Foo> groupByResult = empList.stream().collect(groupingBy(department,
                Collector.of(
                        () -> {
                            return new Foo();
                        },
                        (result, emp) -> {
                            result.setAgeSum(result.getAgeSum() + emp.getAge());
                            result.setSalarySum(result.getSalarySum() + emp.getSalarySum());
                            result.setSalaryCount((result.getSalaryCount()) + 1);
                            result.setAgeCount(result.getAgeCount() + 1);
                        },
                        (result1, result2) -> {
                            result1.setSalarySum(result1.getSalarySum() + result2.getSalarySum());
                            result1.setAgeSum(result1.getAgeSum() + result2.getAgeSum());
                            result1.setAgeCount(result1.getAgeCount() + result2.getAgeCount());
                            result1.setSalaryCount(result1.getSalaryCount() + result2.getSalaryCount());
                            return result1;
                        }
        ));
avr
  • 1
  • 1
  • 4