用于求和 float java 8 的自定义收集器实现
Custom Collector Implementation for summing float java 8
我正在尝试创建类似于 Collectors.summingDouble()
的自定义浮动加法。
但我遇到了 2 个问题,我不确定如何解决。
BiConsumer
- 第 27 行 - void 方法不能 return 值
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
}
如果求和是重点。你可以试试下面的方法。
float FtotalSal = (float) lstEmployee.stream().mapToDouble(e -> e.getSal()).sum();
看来,你搞糊涂了Reduction with Mutable Reduction。
您的函数 (val, e) -> val + e.getSal()
和 (val1, val2) -> val1 + val2)
适用于 Reduction 运算,但不适用于 collect
。供应商生产的 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
);
当然,这只是为了练习,因为您已经证明知道使用内置功能的更简单的解决方案。
我正在尝试创建类似于 Collectors.summingDouble()
的自定义浮动加法。
但我遇到了 2 个问题,我不确定如何解决。
BiConsumer
- 第 27 行 - void 方法不能 return 值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
}
如果求和是重点。你可以试试下面的方法。
float FtotalSal = (float) lstEmployee.stream().mapToDouble(e -> e.getSal()).sum();
看来,你搞糊涂了Reduction with Mutable Reduction。
您的函数 (val, e) -> val + e.getSal()
和 (val1, val2) -> val1 + val2)
适用于 Reduction 运算,但不适用于 collect
。供应商生产的 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
);
当然,这只是为了练习,因为您已经证明知道使用内置功能的更简单的解决方案。