# expression-calculator-project **Repository Path**: lmaos/expression-calculator-project ## Basic Information - **Project Name**: expression-calculator-project - **Description**: 面向 Java 的高性能表达式解析计算引擎,支持运算、变量、函数调用,提供双实现架构与高度可扩展能力。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-04-15 - **Last Updated**: 2026-04-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # expression-calculator `expression-calculator` 是一个面向 Java 的表达式计算库,支持算术、比较、逻辑、位运算、变量、字面量,以及公开字段/方法访问。 ## 中央仓库依赖 已发布到 Maven Central,可直接引用: ```xml com.clmcat.commons expression-calculator 1.0.0 ``` ## 能力 - 两种实现:`RecursiveExpressionCalculator`、`IterativeExpressionCalculator` - 支持表达式求值:`calculation(String, Map)` - 支持布尔求值:`compareCalculation(String, Map)` - 支持原始值求值:`evaluate(String, Map)` - 支持模板格式化:`DefaultExpressionFormat` / `ExpressionFormat` - 支持变量、字符串/字符字面量、括号、公开字段访问和链式方法调用 - 支持 `[]` 下标访问与 `(type)` 类型转换 - 支持默认运算符:`+ - * / % ** ! ~ << >> >>> <<< & | ^` - 整数算术结果会尽量保留 `Integer` / `Long`,非整数仍使用 `BigDecimal` ## 运算符符号表 | 分类 | 符号 | 说明 | | --- | --- | --- | | 算术 | `+` `-` `*` `/` `%` `**` | `**` 表示幂运算 | | 位运算 | `~` `<<` `>>` `>>>` `<<<` `&` | `^` | `^` 表示位异或,`<<<` 是 `<<` 的对称别名 | | 比较 | `==` `!=` `>` `<` `>=` `<=` | 比较表达式可与算术/位运算组合 | | 逻辑 | `!` `&&` `||` | `!` 用于单独条件/布尔结果取反,`&&`/`||` 保留短路语义 | ## 快速开始 ```java Map variables = new HashMap(); variables.put("a", 1); variables.put("b", 2); variables.put("c", 3); ExpressionCalculator calculator = new IterativeExpressionCalculator(); String arithmetic = calculator.calculation("a + b * (c + 2)", variables); boolean logic = calculator.compareCalculation("a + b > 2 && c == 3", variables); Object raw = calculator.evaluate("a + b", variables); ``` ## 新能力示例 ### 原始值求值 ```java Object intValue = calculator.evaluate("1 + 2", variables); // Integer(3) Object longValue = calculator.evaluate("1 + 2L", variables); // Long(3) Object decimal = calculator.evaluate("1 + 2.0", variables); // BigDecimal(3) Object bool = calculator.evaluate("a < b || c == 3", variables);// Boolean.TRUE ``` ### 模板格式化 ```java ExpressionFormat formatter = new DefaultExpressionFormat(calculator); variables.put("numbers", new String[] {"a", "b", "c"}); String text = formatter.format("1 + 2 = ${1 + 2}", variables); // 1 + 2 = 3 String escaped = formatter.format("\\${a + b}", variables); // ${a + b} String custom = formatter.format("#{a + b}", "#{?}", variables);// 3 String fieldText = formatter.format("len=${numbers.length}", variables); // len=3 ``` `ExpressionFormat.format(...)` 始终返回 `String`,即使占位表达式的原始值是数字或布尔值。 如需按类型自定义模板输出,可传入带配置的输出注册器: ```java OutputFormatRegistry registry = OutputFormatRegistry.getInstance().copy(); registry.setOption(byte[].class, "mode", "base64"); registry.setOption(File.class, "mode", "content"); registry.setOption(File.class, "charset", "UTF-8"); registry.setOption(Date.class, "pattern", "yyyyMMdd"); registry.setOption(Date.class, "timeZone", "UTC"); String customText = formatter.format( "bytes=${payload}|file=${file}|date=${createdAt}", "${?}", variables, registry); ``` 内置输出选项: | 类型 | 可用选项 | | --- | --- | | `byte[]` | `mode=text/base64/hex`,`charset` | | `File` | `mode=path/name/content`,`charset` | | `Date` | `pattern`,`timeZone` | 旧的 2/3 参 `format(...)` 会继续走全局默认注册器;如需按次调用隔离配置,建议先使用 `copy()` 再传入。 ### 公开字段与方法访问 表达式可直接访问变量中的对象的公开字段和方法: (public fields and methods) ```java variables.put("numbers", new String[] {"a", "b", "c"}); variables.put("return.value", "success"); variables.put("str", "hello world"); Object length = calculator.evaluate("numbers.length", variables); // Integer(3) String value = calculator.calculation("\"copilot\".length()", variables); // "7" Object dotted = calculator.evaluate("return.value", variables); // "success" Object substring = calculator.calculation("str.substring(0, 4)", variables); ``` ### 下标访问与类型转换 ```java Map inventory = new HashMap(); inventory.put("count", 3); variables.put("inventory", inventory); variables.put("numbers", Arrays.asList(10, 20, 30)); variables.put("index", 1); Object item = calculator.evaluate("numbers[index]", variables); // 20 Object count = calculator.evaluate("inventory['count']", variables); // 3 Object casted = calculator.evaluate("(String)(inventory['count'] + 2)", variables); // "5" ``` ### 自定义类型转换器 ```java ConverterRegistry converterRegistry = ConverterRegistry.getInstance(); converterRegistry.register("wrapped", value -> value == null ? null : "[" + value + "]"); Object wrapped = calculator.evaluate("(wrapped)123", variables); // "[123]" ``` ## 构建与测试 进入模块目录后执行: ```powershell cd expression-calculator mvn test ``` ## 依赖方式 先把库安装到本地 Maven 仓库: ```powershell cd expression-calculator mvn clean install ``` 然后在你的 `pom.xml` 中加入: ```xml com.clmcat.commons expression-calculator 1.0.0 ``` 如果你在多模块工程中使用,也可以直接依赖本地安装后的坐标,无需额外引入第三方依赖。 ## 说明 - `**` 是幂运算符,`^` 是位异或运算符 - `!` 可用于 `compareCalculation` 中对单独变量、集合、文件或返回布尔值的方法结果做取反 - 所有 README 示例都保持 Java 8 兼容, - 自定义运算符注册说明见 [README_EXTENSIBILITY.md](expression-calculator/README_EXTENSIBILITY.md) - 其他参考: - [usage-guide-zh.md](docs/usage-guide-zh.md) - [usage-guide-en.md](docs/usage-guide-en.md)