错误示范:
package udf;
import org.apache.flink.table.functions.AggregateFunction;
//第一个Double为返回值类型,第二个Double为累加器的类型
public class AggFuncWithBaseType extends AggregateFunction<Double, Double> {
@Override
public Double getValue(Double acctor) {
return acctor;
}
@Override
public Double createAccumulator() {
return new Double(0.0);
}
public void accumulate(Double acctor, Double value) {
acctor += value;
}
}
错误分析:
我们先来看看Double的参数调用传递问题:
public class DoubleTest {
public static Double d1 = new Double(10.0);
public static Double d2 = new Double(20.0);
public static void main(String[] args) {
add(d1, d2);
System.out.println(d1);
}
public static void add(Double a, Double b){
System.out.println("相加前,a==d1:"+(a==d1));
a = a + b;
System.out.println("相加后,a==d1:"+(a==d1));
}
}
//
//输出结果:
//相加前,a==d1:true
//相加后,a==d1:false
//10.0
//
可见两个Double相加,返回的是一个新的Double对象,因此add方法,并不能对传入的参数对象进行值的改变。
所以,在我们程序中,累加器不能使用基本包装数据类型,如果简单起见,其实也可以选择JUC中的 DoubleAdder 这类封装对象来作为累加器。
package udf;
import org.apache.flink.table.functions.AggregateFunction;
import java.util.concurrent.atomic.DoubleAdder;
public class AggFuncWithAtomic extends AggregateFunction<Double, DoubleAdder> {
@Override
public Double getValue(DoubleAdder acctor) {
return acctor.doubleValue();
}
@Override
public DoubleAdder createAccumulator() {
DoubleAdder doubleAdder = new DoubleAdder();
doubleAdder.reset();
return doubleAdder;
}
public void accumulate(DoubleAdder acctor, Double value) {
acctor.add(value);
}
}
问题解决!