用于汇总float java 8的定制收集器实现

问题描述 投票:2回答:2

我正在尝试创建类似于Collectors.summingDouble()的自定义浮点加法。

但是我面临2个问题,不确定如何解决。

  1. [BiConsumer-第27行-void方法无法返回值]
  2. [Collectors.of-第32行-类型Collector中的(Supplier,BiConsumer<R,T>BinaryOperator<R>,Collector.Characteristics ...)自变量(Supplier<Float[]>BiConsumer<Float,Employee>BinaryOperator<Float>)解决此问题需要在这里做什么?
public class CustomCollector {


    public static void main(String[] args) {
        Employee e1=new Employee(1,"Tom",10.2f);
        Employee e2=new Employee(1,"Jack",10.4f);
        Employee e3=new Employee(1,"Harry",10.4f);
        ArrayList<Employee> lstEmployee=new ArrayList<Employee>();
        lstEmployee.add(e1);lstEmployee.add(e2);lstEmployee.add(e3);

/*  Implementation 1
 *  double totalSal=lstEmployee.stream().collect(Collectors.summingDouble(e->e.getSal()));
        System.out.println(totalSal);
*/  
        //Implementation 2
        Function<Employee,Float> fun=(e)->e.getSal();
        BiConsumer<Float,Employee> consumer=(val,e)->val+e.getSal();
        BinaryOperator<Float> operator=(val1,val2)->val1+val2;
        Supplier<Float[]> supplier=() -> new Float[2];

        float FtotalSal=lstEmployee.stream().collect(
                Collector.of(supplier,consumer,operator));
        System.out.println(FtotalSal);
    }

}

class Employee {
    int id;
    String name;
    float sal;
    // getters, setter, constructror
}
java java-8 java-stream collectors
2个回答
5
投票

看来,您正在将ReductionMutable Reduction混淆。

您的功能(val, e) -> val + e.getSal()(val1, val2) -> val1 + val2)适用于归约运算,但不适用于collect。供应商生产的长度为2的Float[]数组完全不适合它。

例如,您可以使用]进行操作>

float f = lstEmployee.stream().reduce(
    0F,
    (val, e) -> val + e.getSal(),
    (val1, val2) -> val1 + val2);

[这负担了一些装箱开销,因为所有中间和都表示为Float对象。

[当创建一个可变容器时可以使用Mutable Reduction来避免这种情况,该容器可以不装箱而保存float值,即new float[1]。然后,您必须提供接受数组参数并更改包含的值的函数。由于您的预期结果是float而不是数组,因此您进一步需要finisher

才能产生最终结果。
float f = lstEmployee.stream().collect(
    Collector.of(
        () -> new float[1], // a container capable of holding one float
        (floatArray,e) -> floatArray[0] += e.getSal(), // add one element to the array
        (a1, a2) -> { a1[0] += a2[0]; return a1; }, // merge two arrays
        array -> array[0]) // extracting the final result value
    );

当然,这仅是用于锻炼,因为您已经显示出知道使用内置功能的简单解决方案。


0
投票

如果获得总和是重点。您可以尝试以下类似方法。

© www.soinside.com 2019 - 2024. All rights reserved.