简体   繁体   English

对浮点数求和的自定义收集器实现 java 8

[英]Custom Collector Implementation for summing float java 8

I am trying to create a custom float addition similar to Collectors.summingDouble() .我正在尝试创建一个类似于Collectors.summingDouble()的自定义浮动添加。

But I am facing 2 issues and I am not sure about how to fix it.但我面临两个问题,我不确定如何解决它。

  1. BiConsumer - Line #27 - void methods cannot return a value BiConsumer - 第 27 行 - void 方法不能返回值
  2. Collectors.of - Line#32 - The method of(Supplier, BiConsumer<R,T> , BinaryOperator<R> , Collector.Characteristics...) in the type Collector is not applicable for the arguments ( Supplier<Float[]> , BiConsumer<Float,Employee> , BinaryOperator<Float> ) What needs to be done here for fixing the issue? Collectors.of - 第 32 行 - Collector 类型中的 (Supplier, BiConsumer<R,T> , BinaryOperator<R> , Collector.Characteristics...) 方法不适用于 arguments ( 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
}

It seems, you are confusing Reduction with Mutable Reduction .看来,您将ReductionMutable Reduction混淆了。

Your functions, (val, e) -> val + e.getSal() and (val1, val2) -> val1 + val2) , are suitable for a Reduction operation, but not for collect .您的函数(val, e) -> val + e.getSal()(val1, val2) -> val1 + val2)适用于归约操作,但不适用于collect The supplier, producing a Float[] array of length two, doesn't fit to it at all.供应商生产一个长度为 2 的Float[]数组,根本不适合它。

Eg, you can perform your operation using例如,您可以使用

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

This bears some boxing overhead, as all intermediate sums are represented as Float objects.这会带来一些装箱开销,因为所有中间和都表示为Float对象。

You can avoid this using Mutable Reduction , when you create a mutable container which is capable of holding a float value without boxing, ie new float[1] .您可以使用Mutable Reduction来避免这种情况,当您创建一个能够在不装箱的情况下保存float值的可变容器时,即new float[1] Then, you have to supply functions accepting an array argument and changing the contained value.然后,您必须提供接受数组参数并更改包含值的函数。 Since your intended result is a float , rather than an array, you further need a finisher to produce the final result.由于您的预期结果是float ,而不是数组,因此您还需要一个整理器来产生最终结果。

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
    );

Of course, this is only for exercising, as you have already shown to know a simpler solution using builtin features.当然,这仅用于锻炼,因为您已经展示了使用内置功能了解更简单的解决方案。

If getting the sum is the focus.如果得到总和是重点。 You could try something like below.你可以试试下面的东西。

 float FtotalSal = (float) lstEmployee.stream().mapToDouble(e -> e.getSal()).sum();

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

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