ibit-exp4j
主要是计算类库 exp4j 进一步封装,进而简化公式计算的繁琐构造。exp4j 的用法可参考 wiki exp4j 用法。
maven 依赖引入
<dependency>
<groupId>tech.ibit</groupId>
<artifactId>ibit-exp4j</artifactId>
<version>1.0</version>
</dependency>
FormulaEntity:定义公式实体
IVariable:定义公式变量
FormulaEvaluator:单个公式计算器
FormulaEvaluators:批量公式计算器
定义公式实体,其构造函数如下所示
/**
* 构造函数
*
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
*/
public FormulaEntity(String formulaKey, String formulaPart);
/**
* 构造函数
*
* @param variablePrefix 变量前缀(标识变量)
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
*/
public FormulaEntity(String variablePrefix, String formulaKey, String formulaPart);
说明:
公式键
=公式部分
,如:#a=#b+100
,公式键为:#a
,公式部分为:#b+100
;#
作为变量标识,如:#a=#b+100
,则 a
和 b
为变量;@
,则公式可定义为 @a=@b+100
。IVariable 接口定义了变量的值设置/获取,计算错误设置/获取,计算精度获取。
具体实现有 ResultMapBean 和 ObjectBean。
定义单个公式计算,其构造函数如下所示:
/**
* 构造函数
*
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
*/
public FormulaEvaluator(String formulaKey, String formulaPart);
/**
* 构造函数
*
* @param variablePrefix 变量前缀(标识变量)
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
*/
public FormulaEvaluator(String variablePrefix, String formulaKey, String formulaPart);
/**
* 构造函数
*
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
* @param operators 自定义符号列表
* @param functions 自定义函数列表
*/
public FormulaEvaluator(String formulaKey, String formulaPart
, List<Operator> operators, List<Function> functions);
/**
* 构造函数
*
* @param variablePrefix 变量前缀(标识变量)
* @param formulaKey 公式键(等号左边)
* @param formulaPart 公式部分(等号右边)
* @param operators 自定义符号列表
* @param functions 自定义函数列表
*/
public FormulaEvaluator(String variablePrefix, String formulaKey, String formulaPart
, List<Operator> operators, List<Function> functions);
说明:
variablePrefix
、formulaKey
和 formulaPart
跟公式实体定义相关;operators
为自定义符号,exp4j 支持自定义符号,如 $
,>
,==
等;functions
为自定义方法,exp4j 支持自定义函数,如 min
,max
等。公式计算方法:
/**
* 计算
*
* @param iVariable 计算变量值
* @return 计算结果
*/
public Double evaluate(IVariable iVariable);
说明:
!
开头,则为强制计算,公式部分中的变量如果有null值,则使用默认值替换;N!
开头,公式中任意变量为 null,则返回 null;!
或 N!
开头,公式中全部变量为 null,则返回 null。示例 demo 如下,更多示例参考:FormulaEvaluatorTest
@Test
public void evaluate9() {
IVariable variable = ResultMapBean.getInstance(4, 2, BigDecimal.ZERO);
variable.setValue("a", BigDecimal.TEN);
variable.setValue("b", BigDecimal.ONE);
FormulaEvaluator evaluator = new FormulaEvaluator("#", "#c", "min(#a, #b$)"
, OperatorEnhanceUtils.getOperators(), MathFunctionEnhanceUtils.getFunctions());
assertEquals(BigDecimal.ONE.doubleValue(), evaluator.evaluate(variable), 0);
evaluator = new FormulaEvaluator("#", "#c", "abs(#b)"
, OperatorEnhanceUtils.getOperators(), MathFunctionEnhanceUtils.getFunctions());
assertEquals(BigDecimal.ONE.doubleValue(), evaluator.evaluate(variable), 0);
}
定义批量公式计算,其构造函数如下:
/**
* 构造函数
*
* @param variablePrefix 变量前缀
* @param formulaProperties 公式配置(公式键:公式部分)
*/
public FormulaEvaluators(String variablePrefix, Map<String, String> formulaProperties);
/**
* 构造函数
*
* @param variablePrefix 变量前缀
* @param formulaProperties 公式配置(公式键:公式部分)
* @param operators 自定义操作符
* @param functions 自定义操作符
*/
public FormulaEvaluators(String variablePrefix, Map<String, String> formulaProperties
, List<Operator> operators, List<Function> functions);
说明:
variablePrefix
和 formulaProperties
跟公式实体定义相关;operators
为自定义符号,exp4j 支持自定义符号,如 $
,>
,==
等;functions
为自定义方法,exp4j 支持自定义函数,如 min
,max
等。公式计算方法:
/**
* 对每一行记录进行处理,包括如下步骤
* a)公式解析
* b)变量赋值
* c)计算
* d)存储计算结果
*
* @param variable 变量
*/
public void evaluateAll(IVariable variable);
!
开头,则为强制计算,公式部分中的变量如果有null值,则使用默认值替换;N!
开头,公式中任意变量为 null,则返回 null;!
或 N!
开头,公式中全部变量为 null,则返回 null。MathFunctionEnhanceUtils:数学函数扩展(rint,pow,min,max)
OperatorEnhanceUtils:操作符扩展($,//,>,>=,==,<=,<)
exp4j 默认支持函数,查看 exp4j wiki。MathFunctionEnhanceUtils 扩展了 rint
, pow
, min
,max
,公式计算按需加载即可。
OperatorEnhanceUtils 扩展了 exp4j 操作符,按需加载即可,扩展操作符说明如下:
操作符 | 说明 |
---|---|
$ | 如果分母为0,则抛 ArithmeticException 如:a/b$,b 为 0 时,抛 ArithmeticException |
// | 如果分母为 0,则结果返回 0 |
> | a>b,若满足 a>b ,返回 1,否则返回 0 |
>= | a>=b,若满足 a>=b ,返回 1,否则返回 0 |
< | a>=b,若满足 a<b ,返回 1,否则返回 0 |
<= | a>=b,若满足 a<=b ,返回 1,否则返回 0 |
== | a>=b,若满足 a==b ,返回 1,否则返回 0 |
定义关系,当某个变量值发生变化的时候,计算出受影响的节点,进行重新计算。
RelationEntity:关系实体
EffectedRelation:影响关系
RelationEvaluators:关系计算器
定义关系实体。为树节点,可以获取到该节点影响节点。子节点为受影响的节点
定义节点与节点之间的影响关系,1对1。
定义关系计算器,其构造函数如下所示:
/**
* 构造函数
*
* @param formulaEntities 公式实体
*/
public RelationEvaluators(FormulaEntity... formulaEntities);
/**
* 构造函数
*
* @param effectedRelations 关系对
*/
public RelationEvaluators(EffectedRelation... effectedRelations);
说明:
主要方法:
/**
* 获取受影响的节点名称
*
* @param nodeName 节点名称
* @return 受影响的节点名称列表
*/
public Set<String> getEffectedNodeNames(String nodeName);
说明:
示例说明:
假设定义了如下公式(#
为变量标识):
#A=#B/#C
#B=#C-#D
#D=#E+#F
#E=#F+#H
#G=1+2
构造出如下关系树(箭头指向影响节点):
获取节点(H)所影响节点,如下所示:
红色箭头代表影响的节点流转。上图可以看出,节点 H 影响的节点有 E、D、B、A。
批量计算公式时,某个值改变(如 H),只需要重算其影响的节点(E、D、B、A),而不是所有重算。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。