我正在尝试创建类似于Collectors.summingDouble()
的自定义浮点加法。
但是我面临2个问题,不确定如何解决。
BiConsumer
-第27行-void方法无法返回值]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
}
看来,您正在将Reduction与Mutable 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 );
当然,这仅是用于锻炼,因为您已经显示出知道使用内置功能的简单解决方案。
如果获得总和是重点。您可以尝试以下类似方法。