Java 在ApacheDerby中创建用户定义的聚合函数
我需要在Derby中创建一个用户定义的聚合(UDA)函数(特别是Java 在ApacheDerby中创建用户定义的聚合函数,java,derby,Java,Derby,我需要在Derby中创建一个用户定义的聚合(UDA)函数(特别是Variance函数),但我仍然坚持正确的编写方法 到目前为止,我有UDA的“模板”: public class Variance<V extends Comparable<V>> implements Aggregator<V,V,Variance<V>> { private ArrayList<V> _values; public Variance()
Variance
函数),但我仍然坚持正确的编写方法
到目前为止,我有UDA的“模板”:
public class Variance<V extends Comparable<V>> implements Aggregator<V,V,Variance<V>> {
private ArrayList<V> _values;
public Variance() {/*Empty constructor*/}
public void init() {_values = new ArrayList<V>(); }
public void accumulate(V v) { _values.add(v); }
public void merge(Variance<V> o) { _values.addAll(o._values); }
public V terminate() {
// Here is my issue!!!
}
}
公共类实现聚合器{
私有ArrayList_值;
公共方差(){/*空构造函数*/}
public void init(){u values=new ArrayList();}
公共void累积(V){_value.add(V);}
公共void合并(方差o){_值.addAll(o._值);}
公共V终止(){
//这是我的问题!!!
}
}
我面临的问题是:要计算方差,我需要计算如下:
V sum, sumSq;
int n = _values.size();
if(n <= 0)
return null;
// Initialize sum and sumSq to "zero"
for(V v : _values) {
sum += v; // Or somehow add v to sum
sumSq += Math.pow(v, 2); // Or somehow add (v^2) to sumSq
}
return (sumSq - n * Math.pow(sum / n, 2)) / n;
V和,sumSq;
int n=_values.size();
如果(n查看Derby的数据类型:
DECIMAL = java.math.BigDecimal
INTEGER = java.lang.Integer
FLOAT = java.lang.Float or java.lang.Double
FLOAT将根据创建时指定的精度转换为不同的Java对象,默认值为Java.lang.Double
添加数字
您遇到的第一个问题是简单地将值相加(对于二进制运算符“+”错误,有很多错误的操作数类型)。此外,即使您可以使用Integer、Float和Double,您也会发现,由于BigDecimal不直接映射到Java原语,因此它不能与标准原语算术运算符一起工作,并且因此在对象上有自己的add方法
引用
有很多方法可以一起解决,但老实说,
泛型并不是解决这个问题的方法。为每个泛型建立一个方法
具体的原始包装器类型并分别实现它们
算术是一个非常头痛的问题,不能使它通用
操作不能一般发生
平方值
第二个问题是,您使用的是power方法
Math.pow()适用于双参数-因此整数或双精度计算应该可以。Float可能会显示意外的结果,因为将Float转换为double可能会导致转换值中出现奇怪的额外数字
Math.pow的结果类型是Double,您可以通过定义聚合器来解决此问题,以便terminate方法结果类型始终是Double,例如:
public class Variance<V extends Number & Comparable<V>>
implements Aggregator<V, Double, Variance<V>> {
公共类变量
实现聚合器{
正如我们前面所看到的,BigDecimal与其他方法略有不同,它有自己的pow()方法,其结果类型是BigDecimal值
结论
鉴于上述情况,我建议不要尝试通用解决方案,而是为您想要支持的每种类类型实现多个方差聚合器。例如,您可以实现如下内容:
Aggregator<Integer, Double, Variance<Integer>>
Aggregator<Double, Double, Variance<Double>>
Aggregator<Float, Double, Variance<Float>>
Aggregator<BigDecimal, BigDecimal, Variance<BigDecimal>>
聚合器
聚合器
聚合器
聚合器
//这不是最好的答案,但很有效
导入org.apache.derby.agg.Aggregator;
导入java.util.ArrayList;
公共类聚合器{
private ArrayList list=null;
公共方差(){}
公共void init(){
列表=新的ArrayList();
}
公共空间累积(V值){
列表。添加(值);
}
公共无效合并(另一个){
list.addAll(另一个.list);
}
公共V终止(){
双和=0,sumSq=0;
int n=list.size();
如果有什么解释就好了!
//that is not the best answer, but works
import org.apache.derby.agg.Aggregator;
import java.util.ArrayList;
public class Variance<V extends Double> implements Aggregator<V,V,Variance<V>> {
private ArrayList<V> list =null;
public Variance() {}
public void init() {
list= new ArrayList<>();
}
public void accumulate(V value) {
list.add(value);
}
public void merge(Variance<V> another) {
list.addAll(another.list);
}
public V terminate() {
double sum=0, sumSq=0;
int n = list.size();
if(n <= 0)
return null;
// Initialize sum and sumSq to "zero"
for(Double v : list) {
sum += v; // Or somehow add v to sum
sumSq += Math.pow(v, 2); // Or somehow add (v^2) to sumSq
}
return (V)(new Double((sumSq - n * Math.pow(sum / n, 2)) / n) ) ;
}
public static void main(String [] args) {
Variance<Double> v= new Variance<>();
v.init();
v.accumulate(new Double(8.0));
v.accumulate(new Double(6.0));
v.accumulate(new Double(10.0));
System.out.println(v.terminate());
}
}