Streams Collectors.summingDouble动态函数参数

时间:2017-04-17 17:47:35

标签: lambda java-8 java-stream

我有以下代码,如果我硬编码pojo方法 Employee :: getBaseSalary

Map<Date, Map<String, Double>> $r = list
                                .stream()
                                .filter((p) -> (StringUtils.equalsIgnoreCase(p.getActiveInd(), "Y")
                                                && CoreUtils.greaterThanOrEquals(p.getCreateDate(), paramDate) && (null == p.getEmpDate())))
                                .collect(Collectors.groupingBy(dateFn,
                                         Collectors.groupingBy(empCodeFn,
                                         Collectors.summingDouble(Employee::getBaseSalary))));

问题

请注意,我在group by子句中使用了 dateFn empCodeFn 的java函数对象。我正在尝试对 summingDouble 执行相同操作,但是它会产生编译错误?

    private Function<Employee, Double> getFunctionSpecialCalc() {
    switch (calculationType) {
        case BaseSalary:
            return Employee::getBaseSalary;
        case TotalSalary:
            return Employee::getTotalSalary;
        default:
            return Employee::getBaseSalary;
    }
}

我打算按如下方式使用它:

Function<Employee,Double> calcFn = getFunctionSpecialCalc();
...
...    
Collectors.summingDouble(calcFn))));

编译错误 收集器类型中的summingDouble(ToDoubleFunction)方法不适用于参数(Function)

我知道它现在需要函数类型为 ToDoubleFunction ,但现在问题是如何将动态函数注入SummingDouble?

解决方案 经过调查,我找到了以下解决方案。它不像使用Function Object那么棒和干净。如果您有更好解决问题的方法,请更新。

        Collectors.summingDouble((o)->{if(Type.BaseSalary.equals(calculationType)) 
      return o.getBaseSalary();
 else return o.getTotalSalary();
}))));

1 个答案:

答案 0 :(得分:2)

我认为你不应该在collect部分做这一步;相反它应该是某些map的一部分。但由于这是Collector的一部分,我会选择Collectors.mapping,如下所示:

Map<Date, Map<String, Double>> $r = list
       .stream()
       .filter((p) -> (StringUtils.equalsIgnoreCase(p.getActiveInd(), "Y")
                                            && CoreUtils.greaterThanOrEquals(p.getCreateDate(), paramDate) && (null == p.getEmpDate())))
       .collect(Collectors.groupingBy(dateFn,
             Collectors.groupingBy(empCodeFn,
             Collectors.mapping(o-> {
                   if(Type.BaseSalary.equals(calculationType)) 
                        return o.getBaseSalary();
                   else return o.getTotalSalary();
             }, Collectors.summingDouble(x -> x)
   ))));