You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
456/EmployeeSystem/EmployeeStatistics.java

230 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import java.time.LocalDate;
import java.time.Period;
import java.util.*;
import java.util.stream.Collectors;
/**
* 员工统计类 - 负责生成复杂的统计报告
* 遵循单一职责原则:只负责员工数据的统计分析逻辑
*/
public class EmployeeStatistics {
/**
* 计算员工薪资总额
* @param employees 员工列表
* @return 薪资总额
*/
public double calculateTotalSalary(List<Employee> employees) {
return employees.stream()
.mapToDouble(Employee::getSalary)
.sum();
}
/**
* 计算员工平均薪资
* @param employees 员工列表
* @return 平均薪资
*/
public double calculateAverageSalary(List<Employee> employees) {
if (employees.isEmpty()) {
return 0;
}
return calculateTotalSalary(employees) / employees.size();
}
/**
* 获取最高薪资
* @param employees 员工列表
* @return 最高薪资
*/
public double getMaxSalary(List<Employee> employees) {
if (employees.isEmpty()) {
return 0;
}
return employees.stream()
.mapToDouble(Employee::getSalary)
.max()
.orElse(0);
}
/**
* 获取最低薪资
* @param employees 员工列表
* @return 最低薪资
*/
public double getMinSalary(List<Employee> employees) {
if (employees.isEmpty()) {
return 0;
}
return employees.stream()
.mapToDouble(Employee::getSalary)
.min()
.orElse(0);
}
/**
* 计算部门薪资分布
* @param employees 员工列表
* @return 部门薪资分布映射(部门 -> 薪资统计)
*/
public Map<String, DepartmentSalaryStats> calculateDepartmentSalaryDistribution(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment))
.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> {
List<Employee> deptEmployees = entry.getValue();
double totalSalary = deptEmployees.stream().mapToDouble(Employee::getSalary).sum();
double avgSalary = deptEmployees.isEmpty() ? 0 : totalSalary / deptEmployees.size();
double maxSalary = deptEmployees.stream().mapToDouble(Employee::getSalary).max().orElse(0);
double minSalary = deptEmployees.stream().mapToDouble(Employee::getSalary).min().orElse(0);
return new DepartmentSalaryStats(totalSalary, avgSalary, maxSalary, minSalary, deptEmployees.size());
}
));
}
/**
* 计算员工年龄分布
* @param employees 员工列表
* @return 年龄分布映射(年龄段 -> 人数)
*/
public Map<String, Long> calculateAgeDistribution(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
e -> {
int age = e.getAge();
if (age < 25) return "25岁以下";
else if (age < 35) return "25-34岁";
else if (age < 45) return "35-44岁";
else if (age < 55) return "45-54岁";
else return "55岁以上";
},
Collectors.counting()
));
}
/**
* 计算员工司龄分布
* @param employees 员工列表
* @return 司龄分布映射(司龄段 -> 人数)
*/
public Map<String, Long> calculateTenureDistribution(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(
e -> {
int tenure = e.getTenure();
if (tenure < 1) return "不足1年";
else if (tenure < 3) return "1-2年";
else if (tenure < 5) return "3-4年";
else if (tenure < 10) return "5-9年";
else return "10年以上";
},
Collectors.counting()
));
}
/**
* 计算部门人数分布
* @param employees 员工列表
* @return 部门人数分布映射(部门 -> 人数)
*/
public Map<String, Long> calculateDepartmentHeadcount(List<Employee> employees) {
return employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
}
/**
* 获取指定年份入职的员工数
* @param employees 员工列表
* @param year 年份
* @return 该年份入职的员工数
*/
public long getHireCountByYear(List<Employee> employees, int year) {
return employees.stream()
.filter(e -> e.getHireDate().getYear() == year)
.count();
}
/**
* 计算性别分布如果Employee类中有性别属性
* 这里作为示例假设Employee类有gender属性
* @param employees 员工列表
* @return 性别分布映射(性别 -> 人数)
*/
// 由于Employee类中没有性别属性此方法作为示例保留
public Map<String, Long> calculateGenderDistribution(List<Employee> employees) {
// 实际实现需要在Employee类中添加gender属性
System.out.println("注意Employee类中暂未添加性别属性无法计算性别分布");
return new HashMap<>();
}
/**
* 获取薪资排名前N的员工
* @param employees 员工列表
* @param n 数量
* @return 薪资最高的N名员工
*/
public List<Employee> getTopNSalaryEmployees(List<Employee> employees, int n) {
if (n <= 0) {
throw new IllegalArgumentException("N必须为正整数");
}
return employees.stream()
.sorted(Comparator.comparingDouble(Employee::getSalary).reversed())
.limit(n)
.collect(Collectors.toList());
}
/**
* 计算在职率
* @param employees 员工列表
* @return 在职率(百分比)
*/
public double calculateActiveRate(List<Employee> employees) {
if (employees.isEmpty()) {
return 0;
}
long activeCount = employees.stream()
.filter(Employee::isActive)
.count();
return (double) activeCount / employees.size() * 100;
}
/**
* 部门薪资统计内部类
*/
public static class DepartmentSalaryStats {
private final double totalSalary;
private final double averageSalary;
private final double maxSalary;
private final double minSalary;
private final int headcount;
public DepartmentSalaryStats(double totalSalary, double averageSalary,
double maxSalary, double minSalary, int headcount) {
this.totalSalary = totalSalary;
this.averageSalary = averageSalary;
this.maxSalary = maxSalary;
this.minSalary = minSalary;
this.headcount = headcount;
}
public double getTotalSalary() { return totalSalary; }
public double getAverageSalary() { return averageSalary; }
public double getMaxSalary() { return maxSalary; }
public double getMinSalary() { return minSalary; }
public int getHeadcount() { return headcount; }
@Override
public String toString() {
return "部门薪资统计{" +
"总薪资= " + totalSalary +
", 平均薪资= " + String.format("%.2f", averageSalary) +
", 最高薪资= " + maxSalary +
", 最低薪资= " + minSalary +
", 人数= " + headcount +
"}";
}
}
}