第一节: 基于JS引擎实现布尔和四则的混合运算

· 基本介绍

 开发需求: 实现既支持算术又支持逻辑的表达式运算(返回算术值或布尔值)

· 过程分析

  网上提供的方案如下:

       1、 基于栈或队列来实现基本的算术运算

       2、基于模板引擎(js、Nashorn、javascript等)

网上的很多方案都是基于栈或队列思想的四则运算,并没有将其和布尔运算结合在一起的情况,独立实现一个要考虑排除非法字符、运算符优先级等各种问题,耗时会比较多,于是我就选择考虑使用一些JS引擎来实现混合运算。

本来想着直接将表达式放入JS引擎中就可以得到

· 存在问题

   1、 底层JS引擎计算时会默认把 true 转化为1 ,false转化为0 (解决: 分支思想)

   2、对于&&、|| 结尾的字符串表达式并不报错,其会直接删除, 判断为合理(解决: 添加校验逻辑)

· 实现及思路分析

image.png

· 实现过程

1、 使用前提: 引入依赖 jep 

<dependency>
  <groupId>jep</groupId>
  <artifactId>jep</artifactId>
  <version>2.24</version>
</dependency>

2、基于JS引擎拆解执行逻辑(思想: 采用归并思想)

import com.monitor.common.exception.ServiceException;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description : 表达式计算工具类
 */
public class ExpressionUtil {
    /**
     * 逻辑运算符 ||
     */
    static final String EXPRESSION_OR="||";
    /**
     * 逻辑运算符 &&
     */
    static final String EXPRESSION_AND="&&";
    /**
     * 逻辑运算符 &
     */
    static final String EXPRESSION_SINGLE_AND="&";

    /**
     * 逻辑运算符 |
     */
    static final String EXPRESSION_SINGLE_OR="|";

    /**
     * 正则匹配 ||
     */
    static final String REGULAR_MATCH_OR="\\|\\|";
    /**
     * 正则表达式匹配中文字符串
     */
    static final String PATTERN_CHINESE = "[\\u4e00-\\u9fa5]+";
    /**
     * 正表达式,匹配单独的 = ,而非 ===、==
     */
    static final String PATTERN_EQUAL = "\\b=\\b";
    /**
     * 错误符号组合列表
     */
    static final String[] COMBINE_LIST = {"*true", "true*", "/true", "true/", "+true", "true+", "-true", "true-",
            "/true", "true/", "%true", "%false", "false%", "true%", "*false", "false*", "/false", "false/", "+false", "false+", "-false", "false-",
            ">true", "<true", ">false", "<false", ">=true", "<=true", ">=false", "<=false"};
    /**
     * 暂不支持符号列表
     */
    final static String[] SYMBOL_LIST = {"++","--", ">>","<<",  ">>>", "^", "[", "]", "{", "}", "?:", "instanceof", "+=", "-=", "*=",
            "/=", "%=", ">>=", "<<=", ">>>=", "&=", "|=", "^=", "&&=", "||=", "?:"};
    /**
     * 非法字符列表(待完善)
     */
    final static String[] ILLEGAL_LIST = {"@", "#", "$", "~", "null"};
    /**
     * 布尔运算符集合
     */
    final static Set<String> BOOLEAN_SET = new HashSet<>(Arrays.asList("true", "false"));

    /**
     * 表达式校验和计算
     * @param expression 表达式
     * @return 计算结果
     */
    public static Object calculateExpression(String expression) {
        // 非空校验
        if (expression == null || expression.length() == 0) {
            throw new ServiceException("表达式不能为空!");
        }
        // 去除空字符
        expression = expression.replace(" ", "");
        // 排除暂不支持的运算符
        checkSymbols(expression);
        // 排除非法运算符组合
        checkLegality(expression);
        // 创建JS引擎
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");
        // 统计左右括号个数
        char[] array = expression.toCharArray();
        int leftCount = 0,rightCount=0;
        for (char c : array) {
            if (c == '(') {
                leftCount++;
            } else if (c == ')') {
                rightCount++;
            }
        }
        // 根据左右括号的个数执行对应的逻辑
        return getResult(expression, engine, leftCount, rightCount);
    }

    /**
     * 根据左右括号的个数执行对应的计算逻辑
     * @param expression 表达式
     * @param engine JS引擎
     * @param leftCount 左括号个数
     * @param rightCount 右括号个数
     * @return 计算结果
     */
    private static Object getResult(String expression, ScriptEngine engine, int leftCount, int rightCount) {
        Object result = null;
        if (leftCount == 0 && rightCount == 0) {
            result = attainOutcome(expression, engine);
        } else if (leftCount != rightCount) {
            throw new ServiceException("表达式左右括号数量不匹配!");
        } else {
            boolean flag = false;
            char[] charArray = expression.toCharArray();
            for (int i = 0; i < leftCount; i++) {
                int leftIndex = 0,rightIndex = 0;
                // 左括号找最右侧的位置
                for (int j = 0; j < charArray.length; j++) {
                    if (charArray[j] == '(') {
                        leftIndex = j;
                    }
                }
                // 根据左括号位置找离其最近的右括号位置
                for (int j = leftIndex; j < charArray.length; j++) {
                    if (charArray[j] == ')') {
                        rightIndex = j;
                        break;
                    }
                }
                // 取出括号中算式进行计算
                if (rightIndex != 0 && (rightIndex > leftIndex)) {
                    // 拼接字符串
                    String leftString = expression.substring(0, leftIndex);
                    String middleString = expression.substring(leftIndex + 1, rightIndex);
                    String rightString = expression.substring(rightIndex + 1);
                    // 判断是否还需要再次通过JS引擎计算
                    boolean condition = (leftString.length() > 0 || rightString.length() > 0);
                    if ((i == leftCount - 1) || condition) {
                        // 若是还有其他算式,再执行一次计算逻辑
                        flag = true;
                    }
                    // 将中间的字符串放入到JS中进行计算
                    result = attainOutcome(middleString, engine);
                    // 执行完成后,拼接结果,并校验合法性
                    expression = leftString + result.toString() + rightString;
                    checkLegality(expression);
                    // 校验通过将表达式切分成字符数组
                    charArray= expression.toCharArray();
                } else if ((leftIndex > rightIndex)) {
                    throw new ServiceException("表达式括号位置顺序错误!");
                }
            }
            if (flag) {
                // 将最后一次的计算也放入到情况一中执行
                result = attainOutcome(expression, engine);
            }
        }
        return result;
    }

    /**
     * 检验表达式中是否存在暂不支持的字符
     *
     * @param expression 表达式
     */
    private static void checkSymbols(String expression) {
        for (String s : SYMBOL_LIST) {
            if (expression.contains(s)) {
                throw new ServiceException("暂不支持该表达式中的<" + s + ">字符运算");
            }
        }
    }

    /**
     * 过滤非法字符
     *
     * @param expression 表达式
     */
    private static void filterIllegalSymbols(String expression) {
        for (String item : ILLEGAL_LIST) {
            if (expression.contains(item)) {
                throw new ServiceException("表达式中存在非法字符<" + item + ">,请检查");
            }
        }
    }

    /**
     * 校验表达式合法性
     * @param expression 表达式
     */
    private static void checkLegality(String expression) {
        // 过滤运算符 | & =
        if (expression.matches(PATTERN_EQUAL)) {
            throw new ServiceException("底层引擎不支持=运算,请修改");
        } else if (containsChinese(expression)) {
            throw new ServiceException("表达式中存在中文字符,请修改");
        }
        // 非法字符过滤
        filterIllegalSymbols(expression);
        // 表达式前后缀过滤(&&、||)
        boolean condition = expression.startsWith(EXPRESSION_OR) || expression.endsWith(EXPRESSION_OR);
        boolean condition1 = expression.startsWith(EXPRESSION_AND) || expression.endsWith(EXPRESSION_AND);
        if (condition1 || condition) {
            throw new ServiceException("表达式前后缀不符合运算规则,请检查");
        }
        // 错误组合过滤
        for (String s : COMBINE_LIST) {
            if (expression.contains(s)) {
                throw new ServiceException("<" + s + ">不符合运算规则,请检查");
            }
        }
    }

    /**
     * 获取计算结果
     * @param expression 表达式
     * @param engine     JS引擎
     * @return 操作结果
     */
    private static Object attainOutcome(String expression, ScriptEngine engine) {
        Object result = null;
        // 剪枝处理(表达式以||或&&开头或结尾)
        boolean condition = expression.startsWith(EXPRESSION_OR) || expression.endsWith(EXPRESSION_OR);
        boolean condition1 = expression.startsWith(EXPRESSION_AND) || expression.endsWith(EXPRESSION_AND);
        if (condition1 || condition) {
            throw new ServiceException("表达式中&&或||两侧存在空值,请检查");
        }
        // 判断字符串中是否含有 || 符
        if (expression.contains(EXPRESSION_OR)) {
            try {
                // 根据||符号进行拆分成字符串数组
                String[] strList = expression.split(REGULAR_MATCH_OR);
                for (int i = 0; i < strList.length; i++) {
                    // 遍历每个字符数组
                    if (strList[i].contains(EXPRESSION_AND)) {
                        // 存在&&符号
                        String[] list = strList[i].split(EXPRESSION_AND);
                        int amount = list.length;
                        if (amount > 0) {
                            int count = calculateAndCollect(engine, list);
                            //条件过滤及拼接
                            if (count != 0 && count == amount) {
                                int total = 0;
                                StringBuilder sb = new StringBuilder();
                                for (int j = 0; j < list.length; j++, total++) {
                                    if (BOOLEAN_SET.contains(list[j].trim()) && (j != list.length - 1)) {
                                        sb.append(list[j]).append(EXPRESSION_AND);
                                    } else if (BOOLEAN_SET.contains(list[j].trim()) && j == list.length - 1) {
                                        sb.append(list[j]);
                                    } else {
                                        throw new ServiceException(EXPRESSION_AND + "运算符两侧存在非布尔值,表达式错误,请检查");
                                    }
                                }
                                if (total != 0 && total == amount) {
                                    try {
                                        strList[i] = engine.eval(sb.toString()).toString();
                                    } catch (ScriptException e) {
                                        throw new ServiceException("表达式有误,请检查");
                                    }
                                }
                            }
                        }
                    } else {
                        if(strList[i].contains(EXPRESSION_SINGLE_OR)||strList[i].contains(EXPRESSION_SINGLE_AND)){
                            throw new ServiceException("表达式不支持|或&运算,请检查");
                        }
                        strList[i] = engine.eval(strList[i]).toString();
                    }
                }
                StringBuilder sb = new StringBuilder();
                // 拼接字符串
                for (int i = 0; i < strList.length; i++) {
                    if (i != strList.length - 1 && (BOOLEAN_SET.contains(strList[i].trim()))) {
                        sb.append(strList[i]).append(EXPRESSION_OR);
                    } else if (i == strList.length - 1 && (BOOLEAN_SET.contains(strList[i].trim()))) {
                        sb.append(strList[i]);
                    } else {
                        throw new ServiceException(EXPRESSION_OR + "运算符两侧因数存在非布尔值,表达式错误,请检查");
                    }
                }
                // 执行计算逻辑
                result = engine.eval(sb.toString());
            } catch (ScriptException e) {
                throw new ServiceException("表达式有误,请检查");
            }
        } else if (expression.contains(EXPRESSION_AND)) {
            // 存在&&符号
            String[] list = expression.split(EXPRESSION_AND);
            int amount = list.length;
            if (amount > 0) {
                int count = calculateAndCollect(engine, list);
                // 字符串数组拼接和计算
                if (count != 0 && count == amount) {
                    int total = 0;
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < list.length; j++, total++) {
                        if (BOOLEAN_SET.contains(list[j].trim()) && j != list.length - 1) {
                            // 开始进行拼接
                            sb.append(list[j]).append(EXPRESSION_AND);
                        } else if (BOOLEAN_SET.contains(list[j].trim()) && j == list.length - 1) {
                            // 最后一个,直接拼接即可
                            sb.append(list[j]);
                        } else {
                            throw new ServiceException(EXPRESSION_AND + "运算符两侧存在非布尔值,表达式错误,请检查");
                        }
                    }
                    if (total != 0 && total == amount) {
                        try {
                            result = engine.eval(sb.toString());
                        } catch (ScriptException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } else {
            // 情况三: 表达式中不存在 (、)、||、&& 等运算符,直接通过JS引擎计算即可
            if (expression.contains(EXPRESSION_SINGLE_OR)||expression.contains(EXPRESSION_SINGLE_AND)){
                throw new ServiceException("表达式不支持|或&运算,请检查");
            }
            try {
                result = engine.eval(expression);
            } catch (ScriptException e) {
                throw new RuntimeException("表达式有误,请检查!");
            }
        }
        return result;
    }

    /**
     * 计算集合中的每个元素位置表达式
     * @param engine JS引擎
     * @param list   表达式集合
     * @return 计数器结果
     */
    private static int calculateAndCollect(ScriptEngine engine, String[] list) {
        int count = 0;
        // 遍历每个字符数组进行单独计算
        for (int j = 0; j < list.length; j++) {
            // 空值校验
            if (list[j] == null || "".equals(list[j])) {
                throw new ServiceException("表达式运算符" + EXPRESSION_AND + "两侧存在空值,请检查");
            }
            if (BOOLEAN_SET.contains(list[j].trim())) {
                count++;
            } else {
                if(list[j].contains("|")||list[j].contains("&")){
                    throw new ServiceException("表达式不支持|或&运算,请检查");
                }
                try {
                    // 单独计算并赋值
                    list[j] = engine.eval(list[j]).toString();
                    count++;
                } catch (ScriptException e) {
                    throw new ServiceException("表达式有误,请检查");
                }
            }
        }
        return count;
    }

    /**
     * 判断字符串是否包含中文
     * @param str 字符串
     * @return 包含中文返回true
     */
    public static boolean containsChinese(String str) {
        Pattern pattern = Pattern.compile(PATTERN_CHINESE);
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }
}

测试代码:

/**
 * @Description
 */
public class IllegalExpressionTest {
    // 日志对象
    private static final Logger logger = LoggerFactory.getLogger(LegalExpressionTest.class);
    public static void main(String[] args) {
        System.out.println("---------------------------------------------------------------------------非法运算测试--------------------------------------------------");
        // 左右括号位置顺序错误
        logger.info("=>  )1+2( = {}", ExpressionUtil.calculateExpression(")1+2(").toString());

        // 表达式左右括号数量不匹配
        logger.info("=>  )1+2 = {}", ExpressionUtil.calculateExpression(")1+2").toString(  ));

        // 布尔值运算不符合规则
        logger.info("=>  (1>2)+10 = {}", ExpressionUtil.calculateExpression("(1>2)+10").toString());

        // 表达式前后缀不符合运算规则,请检查
        logger.info("=>  || (7>2) = {}", ExpressionUtil.calculateExpression("|| (7>2)").toString());
        logger.info("=>  (7>2) || = {}", ExpressionUtil.calculateExpression("(7>2) ||").toString());
        logger.info("=>  (7>2) && = {}", ExpressionUtil.calculateExpression("(7>2) &&").toString());
        logger.info("=>  &&(7>2) = {}", ExpressionUtil.calculateExpression("&&(7>2)").toString());
        logger.info("=> ((7>2)&&(8>2))&& = {}", ExpressionUtil.calculateExpression("((7>2)&&(8>2))&&").toString());

        // 表达式中&&或||两侧存在空值,请检查(运算表达式直接以 && 或 ||  开头或结尾)
        logger.info("=> ((7>2)&&)&&(8>2) = {}", ExpressionUtil.calculateExpression("((7>2)&&)&&(8>2)").toString());
        logger.info("=> ((7>2)||)&&(8>2) = {}", ExpressionUtil.calculateExpression("((7>2)||)&&(8>2)").toString());

        // 表达式中存在非法字符组合
        logger.info("=>  (1<2)*3 = {}", ExpressionUtil.calculateExpression("(1<2)*3").toString());
        logger.info("=>  (1<2)+3 = {}", ExpressionUtil.calculateExpression("(1<2)+3").toString());
        logger.info("=>  (1<2)-3 = {}", ExpressionUtil.calculateExpression("(1<2)-2").toString());
        logger.info("=>  (1<2)/3 = {}", ExpressionUtil.calculateExpression("(1<2)/3").toString());
        logger.info("=>  (1<2)%3 = {}", ExpressionUtil.calculateExpression("(1<2)<3").toString());

        // 表达式中存在中文字符,请修改
        logger.info("=>  (1<2中文)<3 = {}", ExpressionUtil.calculateExpression("(1<2中文)<3").toString());

        // 表达式不支持|或&运算,请检查
        logger.info("=>  (1|2)||3 = {}", ExpressionUtil.calculateExpression("(1|2)||3").toString());
        logger.info("=>  (1&2)&&3 = {}", ExpressionUtil.calculateExpression("(1&2)&&3").toString());

        // 表达式中存在非法字符<#>,请检查
        logger.info("=>  (1<2)#3 = {}", ExpressionUtil.calculateExpression("(1<2)#3"));
        logger.info("=>  (1<2)@3 = {}", ExpressionUtil.calculateExpression("(1<2)@3"));
        logger.info("=>  (1<2)$3 = {}", ExpressionUtil.calculateExpression("(1<2)$3"));
    }
}
/**
 * @Description
 */
public class LegalExpressionTest {
    /**
     * 日志对象
     */
    private static final Logger logger = LoggerFactory.getLogger(LegalExpressionTest.class);
    public static void main(String[] args) {

        //算术运算
        System.out.println("-------------------------------------------------------------------------算术运算-------------------------------------------------------------------");
        logger.info("=>   1+2 = {}", ExpressionUtil.calculateExpression("1+2").toString());
        logger.info("=>   1-2 = {}", ExpressionUtil.calculateExpression("1-2").toString());
        logger.info("=>   1*2 = {}", ExpressionUtil.calculateExpression("1*2").toString());
        logger.info("=>   1/2 = {}", ExpressionUtil.calculateExpression("1/2").toString());
        logger.info("=>   1%2 = {}", ExpressionUtil.calculateExpression("1%2").toString());

        // 复杂算术运算
        System.out.println("-------------------------------------------------------------------------复杂算术运算------------------------------------------------------------------");
        logger.info("=>   1+2*3 = {}", ExpressionUtil.calculateExpression("1+2*3").toString());
        logger.info("=>   1+2*3/4 = {}", ExpressionUtil.calculateExpression("1+2*3/4").toString());
        logger.info("=>   1+2*(3/4) = {}", ExpressionUtil.calculateExpression("1+2*(3/4)").toString());
        logger.info("=>   1+2*(3/4)*5 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5").toString());
        logger.info("=>   1+2*(3/4)*5%6 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5%6").toString());
        logger.info("=>   1+2*(3/4)*5%6+7-8/9*10%11 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5%6+7-8/9*10%11").toString());
        logger.info("=>   (32+21)%100 ={}", ExpressionUtil.calculateExpression("(32+21)%100").toString());
        logger.info("=>   4.2-(32+21)%100 = {}", ExpressionUtil.calculateExpression("4.2-(32+21)%100").toString());
        logger.info("=>   (32+21)/100 = {}", ExpressionUtil.calculateExpression("(32+21)/100").toString());
        logger.info("=>   4.1+(32+21)/100 = {}", ExpressionUtil.calculateExpression("4.1+(32+21)/100").toString());

        //关系运算
        System.out.println("--------------------------------------------------------------------------关系运算------------------------------------------------------------------");
        logger.info("=>   1>2 = {}", ExpressionUtil.calculateExpression("1>2").toString());
        logger.info("=>   1<2 = {}", ExpressionUtil.calculateExpression("1<2").toString());
        logger.info("=>   1>=2 = {}", ExpressionUtil.calculateExpression("1>=2").toString());
        logger.info("=>   1<=2 = {}", ExpressionUtil.calculateExpression("1<=2").toString());
        logger.info("=>   1==2 = {}", ExpressionUtil.calculateExpression("1==2").toString());
        logger.info("=>   1===2 = {}", ExpressionUtil.calculateExpression("1===2").toString());
        logger.info("=>   1!=2 = {}", ExpressionUtil.calculateExpression("1!=2").toString());
        logger.info("=>   1!==2 = {}", ExpressionUtil.calculateExpression("1!==2").toString());

        // 复杂关系运算
        System.out.println("---------------------------------------------------------------------------复杂关系运算------------------------------------------------------------------");
        logger.info("=>   1>2&&2>3 = {}", ExpressionUtil.calculateExpression("1>2&&2>3").toString());
        logger.info("=>   1>2&&2<3 = {}", ExpressionUtil.calculateExpression("1>2&&2<3").toString());
        logger.info("=>   1>2||2<3 = {}", ExpressionUtil.calculateExpression("1>2||2<3").toString());
        logger.info("=>   (1>2||2<3)&&3>4 = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&3>4").toString());
        logger.info("=>   (1>2||2<3)&&3<4 = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&3<4").toString());
        logger.info("=>   (1>2||2<3)&&(3>4||4<5) = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&(3>4||4<5)").toString());
        logger.info("=>   (1>2||2<3)&&(3<4||4>5) = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&(3<4||4>5)").toString());

        //逻辑运算
        System.out.println("---------------------------------------------------------------------------逻辑运算------------------------------------------------------------------");
        logger.info("=>   true&&false = {}", ExpressionUtil.calculateExpression("true&&false").toString());
        logger.info("=>   true||false = {}", ExpressionUtil.calculateExpression("true||false").toString());
        logger.info("=>   !true = {}", ExpressionUtil.calculateExpression("!true").toString());
        logger.info("=>   !(7>3) = {}", ExpressionUtil.calculateExpression("!(7>3)"));

        // 复杂逻辑运算
        System.out.println("---------------------------------------------------------------------------复杂逻辑运算------------------------------------------------------------------");
        logger.info("=>   ((6>1)||(true&&(6<2))&&((4<7)||(6>=3))) = {}", ExpressionUtil.calculateExpression("((6>1)||(true&&(6<2))&&((4<7)||(6>=3)))"));

        // 逻辑和算术混合运算
        System.out.println("---------------------------------------------------------------------------逻辑和算术混合运算-----------------------------------------------------");
        logger.info("=>   (1+2>3&&4/2==2) = {}", ExpressionUtil.calculateExpression("(1+2>3&&4/2==2)"));
        logger.info("=>   false&&(4/2==2) = {}", ExpressionUtil.calculateExpression("false&&(4/2==2)"));
        logger.info("=>   true||4/2==2 = {}", ExpressionUtil.calculateExpression("true||4/2==2"));
        logger.info("=>   (1+2>3&&4/2==2)||(false&&(4/2==2)) = {}", ExpressionUtil.calculateExpression("(1+2>3&&4/2==2)||(false&&(4/2==2))"));
    }
}

测试结果(合理):

-------------------------------------------------------------------------算术运算-------------------------------------------------------------------
18:29:05.084 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2 = 3
18:29:05.095 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1-2 = -1
18:29:05.102 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1*2 = 2
18:29:05.109 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1/2 = 0.5
18:29:05.116 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1%2 = 1
-------------------------------------------------------------------------复杂算术运算------------------------------------------------------------------
18:29:05.122 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*3 = 7
18:29:05.127 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*3/4 = 2.5
18:29:05.133 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*(3/4) = 2.5
18:29:05.140 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*(3/4)*5 = 8.5
18:29:05.147 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*(3/4)*5%6 = 2.5
18:29:05.153 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1+2*(3/4)*5%6+7-8/9*10%11 = 0.6111111111111107
18:29:05.160 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (32+21)%100 =53
18:29:05.166 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   4.2-(32+21)%100 = -48.8
18:29:05.171 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (32+21)/100 = 0.53
18:29:05.176 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   4.1+(32+21)/100 = 4.63
--------------------------------------------------------------------------关系运算------------------------------------------------------------------
18:29:05.184 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1>2 = false
18:29:05.188 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1<2 = true
18:29:05.192 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1>=2 = false
18:29:05.195 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1<=2 = true
18:29:05.199 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1==2 = false
18:29:05.202 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1===2 = false
18:29:05.207 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1!=2 = true
18:29:05.212 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1!==2 = true
---------------------------------------------------------------------------复杂关系运算------------------------------------------------------------------
18:29:05.218 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1>2&&2>3 = false
18:29:05.226 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1>2&&2<3 = false
18:29:05.233 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   1>2||2<3 = true
18:29:05.242 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1>2||2<3)&&3>4 = false
18:29:05.249 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1>2||2<3)&&3<4 = true
18:29:05.258 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1>2||2<3)&&(3>4||4<5) = true
18:29:05.267 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1>2||2<3)&&(3<4||4>5) = true
---------------------------------------------------------------------------逻辑运算------------------------------------------------------------------
18:29:05.271 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   true&&false = false
18:29:05.277 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   true||false = true
18:29:05.282 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   !true = false
18:29:05.289 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   !(7>3) = false
---------------------------------------------------------------------------复杂逻辑运算------------------------------------------------------------------
18:29:05.311 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   ((6>1)||(true&&(6<2))&&((4<7)||(6>=3))) = true
---------------------------------------------------------------------------逻辑和算术混合运算-----------------------------------------------------
18:29:05.321 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1+2>3&&4/2==2) = false
18:29:05.329 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   false&&(4/2==2) = false
18:29:05.340 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   true||4/2==2 = true
18:29:05.350 [main] INFO com.jin.demofunction.test.LegalExpressionTest - =>   (1+2>3&&4/2==2)||(false&&(4/2==2)) = false

Process finished with exit code 0
· 总结

  主要实现基于JS表达式引擎的逻辑和算术混合表达式的计算,目前的封装类支持的运算符如下:

  -  小括号 :  ()

  -  基本四则运算符: +、-、*、/、%

  -  判断:  >、<、>= 、<=、!=、==

  -  布尔运算符:  && 、|| 、!

小伙伴们可以根据需要自行扩展! 若发现问题请给我留言,一起进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值