用于求和 java 8 float 的自定义收集器实现

use*_*ght 2 java java-8 java-stream collectors

我正在尝试创建一个类似于 的自定义浮动添加Collectors.summingDouble()

但我面临两个问题,我不知道如何解决它。

  1. BiConsumer- 第 #27 行 - void 方法不能返回值
  2. Collectors.ofBiConsumer<R,T>- 第 32 行 - Collector 类型中的 (Supplier, , , Collector.Characteristics...)方法BinaryOperator<R>不适用于参数 ( 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
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 5

看来,您将ReductionMutable Reduction混淆了。

\n\n

您的函数(val, e) -> val + e.getSal()(val1, val2) -> val1 + val2)适合归约运算,但不适用于collect。供应商生成了一个Float[]长度为 2 的数组,根本不适合它。

\n\n

例如,您可以使用执行操作

\n\n
float f = lstEmployee.stream().reduce(\n    0F,\n    (val, e) -> val + e.getSal(),\n    (val1, val2) -> val1 + val2);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这会带来一些装箱开销,因为所有中间和都表示为Float对象。

\n\n

当您创建一个能够在不装箱的情况下保存值的可变容器(即 )时,您可以使用Mutable Reduction来避免这种情况。然后,您必须提供接受数组参数并更改所包含值的函数。由于您的预期结果是一个,而不是一个数组,因此您还需要一个完成器来生成最终结果。floatnew float[1]float

\n\n
float f = lstEmployee.stream().collect(\n    Collector.of(\n        () -> new float[1], // a container capable of holding one float\n        (floatArray,e) -> floatArray[0] += e.getSal(), // add one element to the array\n        (a1, a2) -> { a1[0] += a2[0]; return a1; }, // merge two arrays\n        array -> array[0]) // extracting the final result value\n    );\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,这仅用于练习,因为您已经证明了使用内置功能了解更简单的解决方案。

\n