如何使用Java Stream仅处理指定Employee子类生成PayrollEntry避免转换异常
不可修改的类层级结构
Employee 类
public abstract class Employee extends Person { private final Manager manager; private final BigDecimal salary; protected Employee(String firstName, String surname, LocalDate birth_date, Manager _manager, BigDecimal _salary) { super(firstName, surname, birth_date); manager = _manager; salary = _salary; if (manager != null) { manager.getSubordinates().add(this); } } // 其余方法省略 }
Worker 类
public class Worker extends Employee { private final LocalDate employment_date; private BigDecimal bonus; public Worker(String firstName, String surname, LocalDate birth_date, Manager manager, BigDecimal salary, LocalDate _employment_date, BigDecimal _bonus) { super(firstName, surname, birth_date, manager, salary); employment_date = _employment_date; bonus = _bonus; } // 其余方法省略 }
Manager 类
public final class Manager extends Worker { List<Employee> subordinates = new ArrayList<Employee>(); public Manager(String firstName, String surname, LocalDate birth_date, Manager manager, BigDecimal salary, LocalDate employment_date, BigDecimal bonus) { super(firstName, surname, birth_date, manager, salary, employment_date, bonus); } // 其余方法省略 }
Trainee 类
public class Trainee extends Employee { private final LocalDate start_date; private final short apprenticeship_length; public Trainee(String firstName, String surname, LocalDate birth_date, Manager manager, BigDecimal salary, LocalDate _start_date, short _apprenticeship_length) { super(firstName, surname, birth_date, manager, salary); manager.getSubordinates().add(this); start_date = _start_date; apprenticeship_length = _apprenticeship_length; } }
PayrollEntry 类
public final class PayrollEntry { private final Employee _employee; private final BigDecimal _salaryPlusBonus; public PayrollEntry(Employee employee, BigDecimal salary, BigDecimal bonus) { _employee = employee; _salaryPlusBonus = salary.add(bonus); } }
需求说明
实现函数 List<PayrollEntry> payroll(List<Employee> employees) {},规则如下:
- 仅
Worker和Manager类实例有bonus Trainee类实例无bonus- 必须使用函数式编程技术实现
现有实现问题
当前代码会抛出ClassCastException,原因是直接将所有Employee实例强转为Worker,但Trainee不属于Worker的继承链:
public static List<PayrollEntry> payroll(List<Employee> employees) { return employees .stream() .map(employee -> new PayrollEntry(employee, employee.getSalary(), ((Worker) employee).getBonus())) .collect(Collectors.toList()); }
解决方案
直接在map操作中加入类型判断即可,Trainee的bonus传入BigDecimal.ZERO:
public static List<PayrollEntry> payroll(List<Employee> employees) { return employees.stream() .map(employee -> { BigDecimal bonus = employee instanceof Worker ? ((Worker) employee).getBonus() : BigDecimal.ZERO; return new PayrollEntry(employee, employee.getSalary(), bonus); }) .collect(Collectors.toList()); }
如果使用Java 16及以上版本,可通过模式匹配简化类型转换代码:
public static List<PayrollEntry> payroll(List<Employee> employees) { return employees.stream() .map(employee -> new PayrollEntry( employee, employee.getSalary(), employee instanceof Worker w ? w.getBonus() : BigDecimal.ZERO )) .collect(Collectors.toList()); }
内容的提问来源于stack exchange,提问作者olimpiabaku
相关产品推荐
相关产品推荐

