gpt4 book ai didi

java - 在 Apache Derby 中创建用户定义的聚合函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:04:03 25 4
gpt4 key购买 nike

我需要在 Derby 中创建一个用户定义的聚合 (UDA) 函数(具体来说,一个 Variance 函数),但我有点坚持使用正确的方法来编写它。

到目前为止,我已经有了 UDA 的"template":

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!!!
}
}

我面临的问题是:要计算方差,我需要这样计算:

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 是数字,因此,我可以对值使用算术运算V 类型。

所以,具体问题是:

  • 有没有办法对值执行此操作(加法、减法、乘积、幂)?
  • 我是否应该更改 V 的定义(某种程度上使其扩展“数字”类,如 Double)?

最佳答案

查看 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 方法。

引用,Mark Peters answer to a similar issue ;

There are ways you can hack this together but in all honestly, generics is simply not the way to go here. Build a method for each concrete primitive wrapper type and implement them separately. It'll be way too much of a headache to make it generic; arithmetic operations can't happen generically.

平方值

您遇到的第二个问题是您使用的是幂法。

Math.pow() 使用双参数 - 因此 Integer 或 Double 计算应该没问题。 Float 可能会显示意外结果,因为将 float 转换为 double 会导致转换值中出现奇怪的额外数字。

Math.pow 的结果类型是 Double,您可以通过定义聚合器来解决这个问题,这样终止方法的结果类型始终是 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>>

关于java - 在 Apache Derby 中创建用户定义的聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24395832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com