简体   繁体   English

如何使用 Double 数据类型减少流

[英]How to reduce streams with Double datatype

I have an ArrayList of user-defined object employee as我有一个用户定义的ArrayList员工的 ArrayList 作为

class Employee {
    String name;
    Double age;
    Double salary
}

I am trying to reduce the above list as a stream via the following code我正在尝试通过以下代码将上述列表减少为 stream

Double totalSalary = empList.stream().parallel().filter(x-> x.getname().equalsIgnoreCase("XYZ")).reduce(0,(subTotal, sal)-> subTotal + dp.getSalary(), DoubleExpression::add);

This does not compile and gives an error.这不会编译并给出错误。 How can I achieve my desired objective?我怎样才能达到我想要的目标?

First you have to map the Employee object into a double salary.首先你得把map把Employee object变成双倍工资。 Then only you can do the reduction step.然后只有你可以做减少步骤。 Moreover, the reduction step takes an identity element and a binary operator.此外,归约步骤采用单位元和二元运算符。 But you have passed three arguments there, which is flawed too.但是你在那里通过了三个arguments,这也是有缺陷的。

double totalSalary = empList.stream()
    .filter(x -> x.getName().equalsIgnoreCase("XYZ"))
    .mapToDouble(Employee::getSalary)
    .sum();

Here's the equivalent reduction.这是等效的减少。 Notice that 0 is the identity element for this reduction.请注意,0 是此归约的标识元素。

double totalSalary = empList.stream()
    .filter(x -> x.getName().equalsIgnoreCase("XYZ"))
    .mapToDouble(Employee::getSalary)
    .reduce(0, Double::sum);

Ravindra's answer provides a correct solution, but to understand in detail why your solution doesn't work, consider these: Ravindra 的回答提供了一个正确的解决方案,但要详细了解您的解决方案为何不起作用,请考虑以下几点:

Double totalSalary = empList.stream().parallel()
        .filter(x -> x.getName().equalsIgnoreCase("XYZ"))
        // crucial aspect of mapping to the type that you want to reduce
        .map(Employee::getSalary)
        // reduction as a stage of stream pipeline execution
        .reduce(0,  // identity element for sum, but with a flaw!!
                (subTotal, sal) -> Double.sum(subTotal, sal), // accumulator to sum double values
                Double::sum // the combiner function compatible with accumulation
               );

The reason why the identity is flawed is that, because of 0, the type of subTotal in the accumulator would not be inferred as double as expected by the Double#sum method.恒等式有缺陷的原因是,由于 0,累加器中的subTotal的类型不会像Double#sum方法所预期的那样被推断为double Hence updating the code further to using Double.NaN would make it work as:因此,进一步更新代码以使用Double.NaN将使其工作为:

Double totalSalary = empList.stream().parallel()
        .filter(x -> x.getName().equalsIgnoreCase("XYZ"))
        .map(Employee::getSalary)
        .reduce(Double.NaN, Double::sum, Double::sum); // identity element and method reference for accumulator

Though note, this could be simply represented with the exclusion of the combiner in this case as:尽管请注意,在这种情况下,这可以通过排除组合器来简单地表示为:

Double totalSalary = empList.stream().parallel()
        .filter(x -> x.getName().equalsIgnoreCase("XYZ"))
        .map(Employee::getSalary)
        .reduce(Double.NaN, Double::sum);

and since sum eventually is an operation of primitive types , it would be much convenient to use the DoubleStream mapping which is a primitive specialization of the stream for double-valued elements.并且由于sum最终是原始类型的操作,因此使用DoubleStream映射会非常方便,它是 stream 对于双值元素的原始特化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM