Необходимо реализовать метод, который будет рассчитывать среднюю зарплату среди всех сотрудников; выводить список подразделений и среднюю зарплату каждого подразделения.
Использую коллекцию Set<Employee> employeeList;
Класс Employee
имеет поля:
private long id;
private String fullName;
private Department department; (enum)
private BigDecimal salary;
Пытался сгруппировать таким образом, чтобы вывести список подразделений и среднюю зарплату, но в моем случае salary типа BigDecimal
и метод averaging
не подходит, т.к. он работает с int, double, long,
а я пытаюсь найти среднее типа BigDecimal
. Наверное такой подход реализовать до конца нет возможности? Тут либо вместо BigDecimal
использовать другой тип или другим путем реализовывать метод. Как пытался делать:
public List<Employee> averageSalaryReport() {
Map<Department, BigDecimal> averageSalaryDepartment = employeeList.stream()
.collect(groupingBy(Employee::getDepartment,averagingInt(Employee::getSalary)));
...
}
P.s. Надеюсь, что более-менее понятно описал суть. Новичок в этом деле. Буду очень благодарен за помощь!
Вместо averagingInt
реализуйте свой Collector
, только для BigDecimal
.
Реализацию averagingInt
посмотреть легко, возьмите её за основу:
public static void main(String[] args) throws Exception {
List<Employee> employees = Arrays.asList(
new Employee(1, "vasya", Department.ONE, BigDecimal.valueOf(100)),
new Employee(2, "fedya", Department.TWO, BigDecimal.valueOf(300)),
new Employee(3, "cj", Department.MAIN, BigDecimal.valueOf(1100)),
new Employee(4, "madonna", Department.TWO, BigDecimal.valueOf(500)),
new Employee(5, "tatyana", Department.MAIN, BigDecimal.valueOf(200)),
new Employee(6, "michael jackson", Department.ONE, BigDecimal.valueOf(500)),
new Employee(7, "petro", Department.ONE, BigDecimal.valueOf(300))
);
Map<Department, BigDecimal> averageSalaryDepartment =
averageSalaryReport(employees);
System.out.println(averageSalaryDepartment);
}
public static Map<Department, BigDecimal> averageSalaryReport(List<Employee> employeeList) {
return employeeList.stream()
.collect(groupingBy(Employee::getDepartment,
Collector.of(() -> new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO},
(a, t) -> { a[0] = a[0].add(t.getSalary()); a[1] = a[1].add(BigDecimal.ONE); },
(a, b) -> { a[0] = a[0].add(b[0]); a[1] = a[1].add(b[1]); return a; },
a -> (a[1].compareTo(BigDecimal.ZERO) == 0) ? BigDecimal.ZERO : a[0].divide(a[1], BigDecimal.ROUND_HALF_UP))));
}
Получилось как-то так ( без создания своего коллектора):
employeeList.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.mapping(Employee::getSalary, Collectors.toList())
))
.forEach((key, list) -> {
final BigDecimal total = list.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal average = total.divide(BigDecimal.valueOf(list.size()));
averageMap.put(key, average);
});
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Мой вопрос написал ниже в комментах программы с достаточно подробным описанием причины возникновения собственно самого вопроса
корректно будет использовать оператор "==" для сравнения двух символов из двух массивов? Не адреса в памята а именно совпадение знаков(если...
Можно ли вызвать определенный метод инициализация сразу после вызова конструктора с помощью аннотаций из javax?
Я делаю приложение на CordovaСтояла задача: создать плагин, который бы создавал фоновый процесс, который в свою очередь каждые 30 секунд отправлял...