规则引擎aviatorEvaluator注意点

规则引擎aviatorEvaluator注意点

官方文档:AviatorScript 编程指南(5.0) · 语雀

1、依赖

        <!--规则引擎--><dependency><groupId>com.googlecode.aviator</groupId><artifactId>aviator</artifactId><version>5.4.3</version></dependency>

2、自定义函数

package com.jayce.boot.route.common.aviatorEvaluator;import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorDecimal;
import com.googlecode.aviator.runtime.type.AviatorObject;import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;public class RoundFunction extends AbstractFunction {private static final long serialVersionUID = 1;@Overridepublic AviatorObject call(final Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {Number number = FunctionUtils.getNumberValue(arg1, env);Number number2 = FunctionUtils.getNumberValue(arg2, env);BigDecimal numberData = new BigDecimal(number.toString());// 四舍五入BigDecimal roundedHalfUp = numberData.setScale(number2.intValue(), RoundingMode.HALF_UP);return AviatorDecimal.valueOf(roundedHalfUp);}@Overridepublic String getName() {return "ROUND";}
}

使用时:

String expression = "ROUND((task_a + task_b) - (task_c/task_d) + task_a*task_c,2)";

Expression compiledExp = AviatorEvaluator.getInstance().compile(expression);

Expression compiledExp = instance.compile(expression);

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("task_a", 3.666666666666666);
paramMap.put("task_b", 7);
paramMap.put("task_c", 1);
paramMap.put("task_d", 2);

Object result = compiledExp.execute(paramMap);

3、关于计算精度问题

// -- 1. 解析浮点数为 Decimal 类型
AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();
instance.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
// -- 2. 解析整数为 Decimal 类型
instance.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);

4、除法变量替换表达式存在bug


如:String expression = "1/2";    result = 0.5;

a=1,b=2;

String expression = "a/b";  result = 0;

得出结果不一样,底层处理可能存在计算漏洞。

临时解决办法,先自行定义规则进行替换,再直接数字直接运算

替换方法:

/*** 替换字符串表达式中的变量为map中对应的值。** @param expression 包含变量的数学表达式* @param values     存储变量及其值的映射* @return 替换后的数学表达式*/public static String replaceVariables(String expression, Map<String, Object> values) {// 正则表达式用于匹配变量名//正则表达式:\\b[a-zA-Z_][a-zA-Z0-9_]*\\b 用于匹配变量名。这里的 \b 是单词边界,确保我们只匹配完整的变量名,而不是部分字符串Pattern pattern = Pattern.compile("\\b[a-zA-Z_][a-zA-Z0-9_]*\\b");Matcher matcher = pattern.matcher(expression);StringBuffer sb = new StringBuffer();while (matcher.find()) {String variable = matcher.group(); // 获取匹配到的变量名if (values.containsKey(variable)) {String replacement = String.valueOf(values.get(variable));// 使用找到的值替换变量matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));} else {// 如果变量不在map中,保留原样matcher.appendReplacement(sb, Matcher.quoteReplacement(variable));}}matcher.appendTail(sb);return sb.toString();}

使用示例:
String expression = "ROUND((task_a + task_b) - (task_c/task_d) + task_a*task_c,2)";

Map<String, Object> paramMap = new HashMap<>();

变量赋值............
//计算逻辑手动替换,自动替换有bug,除法丢精度
expression = replaceVariables(expression, paramMap);

//参数无需传入

Object result = xxx.execute();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

接上一主题,C++14中如何设计类似于std::any,使集合在C++中与Python一样支持任意数据?

这篇文章的重点是C多态的应用&#xff0c;但是如果你是C新手&#xff0c; 你需要了解以下C知识&#xff1a; 类 构造函数 拷贝构造函数 虚拟函数 纯虚拟函数 析构函数 类的继承 运算符重写 模板类 模板参数 数组 数组的传递 指针与动态内存分配 Python&#xff1a; s …

SpringBoot3与JUnit5集成测试

你可以在 Spring Boot 3 中轻松设置和运行 JUnit 集成测试。合理使用 Spring 提供的注解和工具&#xff0c;可以确保测试的高效性和可靠性。以下是集成测试的步骤和示例&#xff1a; 1. 添加依赖 在 pom.xml 中添加 Spring Boot Starter Test 依赖&#xff0c;它包含 JUnit 5 …

【系统架构设计师】真题论文: 论网络安全体系设计(包括解题思路和素材)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2014年 试题4)解题思路论文素材参考网络安全体系设计目标与原则网络安全体系的主要组成部分网络安全体系设计流程真题题目(2014年 试题4) 随着社会信息化的普及,计算机网络已经在各行各业得到了广泛…

5.STM32之通信接口《精讲》之USART通信---实验串口接收程序

根据上节&#xff0c;我们一已经完成了串口发送程序的代码&#xff0c;并且深入的解析探索了串口的原理&#xff0c;接下来&#xff0c;Whappy小编将带领大家进入串口接收程序的探索与实验&#xff0c;并将结合上一节串口发送一起来完成串口的发送和接收实验。 上来两张图 上图…

微服务即时通讯系统的实现(服务端)----(1)

目录 1. 项目介绍和服务器功能设计2. 基础工具安装3. gflags的安装与使用3.1 gflags的介绍3.2 gflags的安装3.3 gflags的认识3.4 gflags的使用 4. gtest的安装与使用4.1 gtest的介绍4.2 gtest的安装4.3 gtest的使用 5 Spdlog日志组件的安装与使用5.1 Spdlog的介绍5.2 Spdlog的安…

macos 使用 nvm 管理 node 并自定义安装目录

系统环境&#xff1a;MacOS Version 参考文章&#xff1a; Github 地址&#xff1a;https://github.com/nvm-sh/nvm 安装的方式是很简单的&#xff0c;直接执行下面的命令即可&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bas…

数字IC后端实现时钟树综合系列教程 | Clock Tree,Clock Skew Group之间的区别和联系

Q: Clock&#xff0c;Clock Tree和Skew Group有何区别&#xff1f;Innovus CCOPT引擎是如何使用这些的&#xff1f; Clock是时序约束SDC中的时钟定义点。 create_clock -name clk_osc -period $period_24m [get_ports xin_osc0_func] 时钟树综合(Clock Tree Synthesis)之前应…

tcpdump抓包 wireShark

TCPdump抓包工具介绍 TCPdump&#xff0c;全称dump the traffic on anetwork&#xff0c;是一个运行在linux平台可以根据使用者需求对网络上传输的数据包进行捕获的抓包工具。 tcpdump可以支持的功能: 1、在Linux平台将网络中传输的数据包全部捕获过来进行分析 2、支持网络层…

安装支持ssl的harbor 2.1.4 docker 19.03.8 docker-compose 1.24.0

版本&#xff1a; docker 19.03.8 docker-compose 1.24.0 harbor: harbor-offline-installer-v2.1.4.tgz 1、先在/root下生成证书 #生成ca根证书 openssl genrsa -out ca.key 4096#创建ca证书 openssl req -x509 -new -nodes -sha512 -days 3650 \-subj "/CCN/STShenzh…

青少年编程等级考试C++一级,硬币反转问题

代码 #include<iostream>using namespace std;bool a[300];int main(){ int n,m; cin >> n >> m; for(int i 1;i < m;i) { for (int j 1;j < n;j) { if( j % i 0) { a[j] !a[j];…

【Qt流式布局改造支持任意位置插入和删除】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、源代码二、删除代码三、扩展总结 前言 最近在做一个需求需要流式布局&#xff0c;虽然官方example里有一个流式布局范例&#xff0c;但是不能满足我的需求…

“AI玩手机”原理揭秘:大模型驱动的移动端GUI智能体

作者&#xff5c;郭源 前言 在后LLM时代&#xff0c;随着大语言模型和多模态大模型技术的日益成熟&#xff0c;AI技术的实际应用及其社会价值愈发受到重视。AI智能体&#xff08;AI Agent&#xff09;技术通过集成行为规划、记忆存储、工具调用等机制&#xff0c;为大模型装上…

小R的二叉树探险 | 模拟

问题描述 在一个神奇的二叉树中&#xff0c;结构非常独特&#xff1a; 每层的节点值赋值方向是交替的&#xff0c;第一层从左到右&#xff0c;第二层从右到左&#xff0c;以此类推&#xff0c;且该二叉树有无穷多层。 小R对这个二叉树充满了好奇&#xff0c;她想知道&#xf…

Unity类银河战士恶魔城学习总结(P141 Finalising ToolTip优化UI显示)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ UI部分暂时完结&#xff01;&#xff01;&#xff01; 本章节优化了UI中物品描述的显示效果&#xff0c;技能描述的显示效果 并且可以批…

快速获取url路径参数方法

如何根据当前url获取路径上的参数值&#xff1f; 例&#xff1a; // 若网页前路径url https://editor.csdn.net/md/?id1&workId2&name小包子方法如下&#xff1a; urlGetParam(param) {const reg new RegExp((^|&)${param}([^&]*)(&|$));const r deco…

windows实现VNC连接ubuntu22.04服务器

最近弄了一个700块钱的mini主机&#xff0c;刷了ubuntu22.04系统&#xff0c;然后想要在笔记本上通过VNC连接&#xff0c;这样就有了一个linux的开发环境。最后实现的过程为&#xff1a; 安装vnc服务器 安装 VNC 服务器软件&#xff1a; sudo apt update sudo apt install t…

Perforce《2024游戏技术现状报告》Part3:生成式AI、版本控制、CI/CD等游戏技术的未来趋势与应用

游戏开发者一直处于创新前沿。他们的实践、工具和技术受到各行各业的广泛关注&#xff0c;正在改变着组织进行数字创作的方式。 近期&#xff0c;Perforce发布了《2024游戏技术现状报告》&#xff0c;通过收集来自游戏、媒体与娱乐、汽车和制造业等高增长行业的从业者、管理人…

初阶数据结构之队列的实现

1 队列的定义 什么是队列呢&#xff1f;队列只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作。队列具有先进先出FIFO(First In First Out)的特性。 队头&#xff1a;删除数据的一端称为队头。 队尾&#xff1a;插入数据的一端称为队尾。 2 队列底层结构…

Linux ss 命令详解

简介 ss 全称 Socket Statistics&#xff0c;是一个用于探究 Linux 上的套接字和网络连接的强大实用程序&#xff0c;它被用来替代老版的 netstat &#xff0c;提供更快、更详细的信息输出。 常用选项 查看所有 sockets ss -a# 显示所有监听和未监听的sockets显示监听的 so…

【C语言】连接陷阱探秘(3):形参、实参与返回值

目录 一、形参的 “迷障” 1.1. 定义与功能 1.2. 类型不匹配 1.3. 数量不一致 1.4. 顺序不一致 1.5. 数组形参退化 二、实参的 “暗礁” 2.1. 定义与功能 2.2. 求值顺序 “谜题” 2.3. 悬空指针 “深渊” 三、返回值的 “陷阱” 3.1. 定义与功能 3.2. 陷阱与缺陷 …