zoukankan      html  css  js  c++  java
  • 【转载】ibit-exp4j

    原文链接:ibit-exp4j

    简介

    ibit-exp4j 主要是计算类库 exp4j 进一步封装,进而简化公式计算的繁琐构造。exp4j 的用法可参考 wiki exp4j 用法

    maven 依赖引入

    <dependency>
        <groupId>tech.ibit</groupId>
        <artifactId>ibit-exp4j</artifactId>
        <version>1.0</version>
    </dependency>
    

    主要类

    公式计算相关

    FormulaEntity

    定义公式实体,其构造函数如下所示

    /**
     * 构造函数
     *
     * @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,则 ab 为变量;
    • 可指定自定义变量前缀,如@,则公式可定义为 @a=@b+100

    IVariable

    IVariable 接口定义了变量的值设置/获取,计算错误设置/获取,计算精度获取。

    具体实现有 ResultMapBeanObjectBean

    FormulaEvaluator

    定义单个公式计算,其构造函数如下所示:

    /**
     * 构造函数
     *
     * @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);
    

    说明:

    • 参数 variablePrefixformulaKeyformulaPart 跟公式实体定义相关;
    • 参数 operators 为自定义符号,exp4j 支持自定义符号,如 $>== 等;
    • 参数 functions 为自定义方法,exp4j 支持自定义函数,如 minmax 等。

    公式计算方法:

    /**
     * 计算
     *
     * @param iVariable 计算变量值
     * @return 计算结果
     */
    public Double evaluate(IVariable iVariable);
    

    说明:

    • iVariable 为计算变量值;
    • 若 formulaKey 以 ! 开头,则为强制计算,公式部分中的变量如果有null值,则使用默认值替换;
    • 若 formulaKey 以 N! 开头,公式中任意变量为 null,则返回 null;
    • 若 formulaKey 不以 !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);
    }
    

    FormulaEvaluators

    定义批量公式计算,其构造函数如下:

    /**
     * 构造函数
     *
     * @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);
    

    说明:

    • 参数 variablePrefixformulaProperties 跟公式实体定义相关;
    • 参数 operators 为自定义符号,exp4j 支持自定义符号,如 $>== 等;
    • 参数 functions 为自定义方法,exp4j 支持自定义函数,如 minmax 等。

    公式计算方法:

    /**
     * 对每一行记录进行处理,包括如下步骤
     * a)公式解析
     * b)变量赋值
     * c)计算
     * d)存储计算结果
     *
     * @param variable 变量
     */
    public void evaluateAll(IVariable variable);
    
    • iVariable 为计算变量值;
    • 若 formulaKey 以 ! 开头,则为强制计算,公式部分中的变量如果有null值,则使用默认值替换;
    • 若 formulaKey 以 N! 开头,公式中任意变量为 null,则返回 null;
    • 若 formulaKey 不以 !N! 开头,公式中全部变量为 null,则返回 null。

    自定义函数和操作符扩展工具类

    MathFunctionEnhanceUtils

    exp4j 默认支持函数,查看 exp4j wiki。MathFunctionEnhanceUtils 扩展了 rintpowminmax,公式计算按需加载即可。

    OperatorEnhanceUtils

    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

    定义节点与节点之间的影响关系,1对1。

    RelationEvaluators

    定义关系计算器,其构造函数如下所示:

    /**
     * 构造函数
     *
     * @param formulaEntities 公式实体
     */
    public RelationEvaluators(FormulaEntity... formulaEntities);
    
    /**
     * 构造函数
     *
     * @param effectedRelations 关系对
     */
    public RelationEvaluators(EffectedRelation... effectedRelations);
    

    说明:

    • 构造函数1:指定公式数组
    • 构造函数2:指定影响关系

    主要方法:

    /**
     * 获取受影响的节点名称
     *
     * @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),而不是所有重算。

  • 相关阅读:
    Elasticsearch学习之深入搜索三 --- best fields策略
    Elasticsearch学习之深入搜索二 --- 搜索底层原理剖析
    Elasticsearch学习之深入搜索一 --- 提高查询的精准度
    Elasticsearch学习之深入聚合分析五---案例实战
    Enigma Virtual Box:生成可执行文件。
    erlang的erl文件的编码方式
    Java相关术语 或者 组件命。
    pyqt5加载网路图片,不本地下载。
    Python3 的json 和 PHP的json
    python3 post方式上传文件。
  • 原文地址:https://www.cnblogs.com/javaDeveloper/p/14079250.html
Copyright © 2011-2022 走看看