Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Stream从超类向下投射到几个子类_Java_Java Stream_Downcast - Fatal编程技术网

Java 使用Stream从超类向下投射到几个子类

Java 使用Stream从超类向下投射到几个子类,java,java-stream,downcast,Java,Java Stream,Downcast,这是我的第一篇文章,这将是一篇艰难的文章 我们有一个Employee类元素列表,它同时可以是5类子类的元素:学徒员工,工薪员工,专员员工,专员员工带薪员工和小时员工,它们都包含在同一个员工列表中 学徒员工:未实施calculateSalary() 受薪员工,委员员工,委员员工,带薪员工和小时员工:实施计算工资() 这个问题需要使用Stream计算平均工资。我已经尝试使用filter和mapingToDouble来完成它。问题是我们不允许使用条件句(如果有的话),因为它说我们使用的是“声明性语言”

这是我的第一篇文章,这将是一篇艰难的文章

我们有一个Employee类元素列表,它同时可以是5类子类的元素:
学徒员工
工薪员工
专员员工
专员员工带薪员工
小时员工
,它们都包含在同一个员工列表中

学徒员工:未实施calculateSalary()

受薪员工,委员员工,委员员工,带薪员工和小时员工:实施计算工资()

这个问题需要使用Stream计算平均工资。我已经尝试使用filter和mapingToDouble来完成它。问题是我们不允许使用条件句(如果有的话),因为它说我们使用的是“声明性语言”,而条件句违背了它的哲学。如何根据元素的子类向下转换元素?我已尝试使用getClass();但是返回的类总是Employee,而不是子类。我试过的代码是:

public Double averageSalary() {
    return  employees.stream()
            .filter(employee -> !(employee instanceof ApprenticeEmployee))
            .mapToDouble(employee -> { 
                (employee.getClass()).cast(employee);
                return employee.calculateSalary();
            })
            .average()
            .getAsDouble();
}
calculateSalary()
是来自接口
Payroll
的一种方法,该方法由5个子类中的4个子类实现,除了
之外,其他所有子类都是
Payroll


对不起,如果我没有以正确的方式键入代码,我是新手!提前谢谢

我建议添加一个接口,其中将分配“calculateSalary”方法。例如,让我们将其命名为“CanCalculateSalary”。该接口将由需要能够计算工资的所有员工类实现。因此,您的代码如下所示:

 return employees.stream()
        .filter(CanCalculateSalary.class::isInstance)
        .mapToDouble(employee -> ((CanCalculateSalary)employee).calculateSalary())
        .average()
        .getAsDouble();

我建议添加一个接口,其中将分配“calculateSalary”方法。例如,让我们将其命名为“CanCalculateSalary”。该接口将由需要能够计算工资的所有员工类实现。因此,您的代码如下所示:

 return employees.stream()
        .filter(CanCalculateSalary.class::isInstance)
        .mapToDouble(employee -> ((CanCalculateSalary)employee).calculateSalary())
        .average()
        .getAsDouble();

有了关于声明方法的接口的信息,就很简单了

public Double averageSalary() {
    return  employees.stream()
            .filter(employee -> employee instanceof Payroll)
            .mapToDouble(employee -> ((Payroll) employee).calculateSalary())
            .average()
            .getAsDouble();
}

这还有更多的优点:它允许将来添加更多的
Employee
子类,其中一些子类可能实现
Payroll
,而有些子类可能不实现。您仍然不需要修改上面的代码(但是使用新的子类再次测试它)。

使用有关接口的信息声明您的方法是简单的

public Double averageSalary() {
    return  employees.stream()
            .filter(employee -> employee instanceof Payroll)
            .mapToDouble(employee -> ((Payroll) employee).calculateSalary())
            .average()
            .getAsDouble();
}

这还有更多的优点:它允许将来添加更多的
Employee
子类,其中一些子类可能实现
Payroll
,而有些子类可能不实现。您仍然不需要修改上面的代码(但使用新的子类再次测试它)。

其他类之间是否存在可派生的关系(除了
)?或者,您认为您应该如何将
专员员工
反对对象转换为
受薪员工
?它们结合在一起的唯一一件事是它们有一个共同的父对象……换句话说,
employees
collection的类型是什么?是否有一个与方法
calculateSalary()
的接口,该方法由您拥有的5个类中的4个实现?
Class.cast()
不会更改给定参数的类型,因此变量
employee
仍然是
employee
对象。但是,
cast()
方法将给定的参数作为所使用的
对象的类型返回。但最终,这种方法在这种情况下对您没有用处。其他类(除了
学徒员工
)之间是否存在可衍生的关系?或者,您认为您应该如何将
专员员工
反对对象转换为
受薪员工
?它们结合在一起的唯一一件事是它们有一个共同的父对象……换句话说,
employees
collection的类型是什么?是否有一个与方法
calculateSalary()
的接口,该方法由您拥有的5个类中的4个实现?
Class.cast()
不会更改给定参数的类型,因此变量
employee
仍然是
employee
对象。但是,
cast()
方法将给定的参数作为所使用的
对象的类型返回。但最终,这种方法在这种情况下对您没有用处。我想您可能需要删除
,因为您正在删除
CanCalculateSalary
atm的实例。(
.filter(CanCalculateSalary.class::isInstance)
是更惯用的方法。)@AndyTurner是的,谢谢。
map(CanCalculateSalary::calculateSalary)
应该可以工作,而不是显式转换。如果没有,那么,
map(CanCalculateSalary.class::cast).mapToDouble(CanCalculateSalary::calculateSalary)
应该可以帮助Sergey!非常感谢,它已经实施并正在运行。我错误地处理了这个问题:我是按子类过滤的,您清楚地告诉我应该按接口过滤。像这样简单。嘿,凯特尔,不客气:)我想你可能想删除
,因为您正在删除
CanCalculateSalary
atm的实例。(
.filter(CanCalculateSalary.class::isInstance)
是更惯用的方法。)@AndyTurner是的,谢谢。
map(CanCalculateSalary::calculateSalary)
应该可以工作,而不是显式转换。如果没有,那么,
map(CanCalculateSalary.class::cast).mapToDouble(CanCalculateSalary::calculateSalary)
应该可以帮助Sergey!非常感谢,它已经实施并正在运行。我错误地处理了这个问题:我是按子类过滤的,您清楚地告诉我应该按接口过滤。像这样简单。嘿,凯特尔,不客气:)谢谢你!我应该把它贴上去