You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Groovy-Ginq的sum函数计算结果错误,求原因与解决方法

问题分析与修复

问题重现

以下代码执行后,预期计算结果为3.4,但实际得到3.2:

public static final String groovyScript= """
            GQ { from o in tuple select sum(o.A) }
            """;

    HashMap<String,Double> a = new HashMap<>();
    a.put("A",1.6);
    HashMap<String,Double> b = new HashMap<>();
    b.put("A",1.8);
    ArrayList<Object> tuple = new ArrayList<>();
    tuple.add(a);
    tuple.add(b);

    GroovyShell groovyShell = new GroovyShell();
    groovyShell.setVariable("tuple", tuple);
    Object result = groovyShell.evaluate(groovyScript);

尝试将HashMap<String,Double>改为HashMap<String,BigDecimal>后,问题依然存在。

原因分析

核心问题出在GQ脚本的sum调用语法错误:

  1. GQ(Groovy Query)的sum(o.A)写法不符合其聚合函数的语法规范,这种写法并未正确遍历所有元素的A属性进行累加,反而错误重复计算了第一个元素的值,最终得到1.6*2=3.2。
  2. 切换为BigDecimal后,由于语法错误未修正,GQ依然无法正确执行聚合求和,因此问题持续存在。

修复方案

方案1:修正GQ的sum语法

若必须使用GQ框架,需将sum调用改为闭包形式,明确指定聚合的属性:

public static final String groovyScript= """
            GQ { from o in tuple select sum{ o.A } }
            """;

方案2:改用Groovy原生sum方法(更可靠)

放弃GQ语法,直接使用Groovy集合的原生sum方法,避免框架语法限制:

public static final String groovyScript= """
            tuple.sum { it.A }
            """;

补充:BigDecimal的精确使用(可选)

如果需要完全避免浮点数精度问题,使用BigDecimal时必须用字符串构造(直接传入double值仍会引入精度损失):

HashMap<String,BigDecimal> a = new HashMap<>();
a.put("A", new BigDecimal("1.6"));
HashMap<String,BigDecimal> b = new HashMap<>();
b.put("A", new BigDecimal("1.8"));

配合Groovy原生sum方法,即可得到精确的3.4结果。

内容的提问来源于stack exchange,提问作者xiaopeng li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:05:34