Java中动态评估AND、OR、NOT逻辑运算的实现方案
扩展支持NOT操作的动态表达式解析实现
核心思路
- 词层扩展:在原有词法规则中加入
NOT关键字识别,明确它是优先级高于AND/OR的单目运算符。 - 语法规则调整:重构表达式解析的层级逻辑,让
NOT可以作用于单个条件或括号包裹的子表达式,语法结构如下:expression → term (OR term)* term → factor (AND factor)* factor → NOT factor | condition | (expression) condition → identifier (EQ | IN) value - 表达式节点扩展:新增
NotExpression类,实现表达式求值接口,核心逻辑是对内部表达式的结果取反。
代码实现示例
假设已基于Tagir Valeev的方案实现了AND/OR及基础条件的解析,以下是扩展NOT操作的完整代码:
1. 表达式核心接口与实现类
import java.util.Map; import java.util.List; // 基础表达式求值接口 interface Expression { boolean evaluate(Map<String, Object> data); } // NOT表达式实现:对内部表达式结果取反 class NotExpression implements Expression { private final Expression innerExpr; public NotExpression(Expression innerExpr) { this.innerExpr = innerExpr; } @Override public boolean evaluate(Map<String, Object> data) { return !innerExpr.evaluate(data); } } // 基础条件表达式(如EmployeeShift='General') class ConditionExpression implements Expression { private final String field; private final Operator operator; private final Object value; public ConditionExpression(String field, Operator operator, Object value) { this.field = field; this.operator = operator; this.value = value; } @Override public boolean evaluate(Map<String, Object> data) { Object actualValue = data.get(field); if (actualValue == null) return false; return switch (operator) { case EQ -> actualValue.equals(value); case IN -> ((List<?>) value).contains(actualValue); }; } enum Operator {EQ, IN} } // 原有AND/OR表达式保持不变 class AndExpression implements Expression { private final Expression left; private final Expression right; public AndExpression(Expression left, Expression right) { this.left = left; this.right = right; } @Override public boolean evaluate(Map<String, Object> data) { return left.evaluate(data) && right.evaluate(data); } } class OrExpression implements Expression { private final Expression left; private final Expression right; public OrExpression(Expression left, Expression right) { this.left = left; this.right = right; } @Override public boolean evaluate(Map<String, Object> data) { return left.evaluate(data) || right.evaluate(data); } }
2. 扩展后的递归下降解析器
import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; class ExpressionParser { private final List<Token> tokens; private int pos; public ExpressionParser(String exprStr) { this.tokens = tokenize(exprStr); this.pos = 0; } // 词法分析:将表达式拆分为Token private List<Token> tokenize(String expr) { List<Token> tokens = new ArrayList<>(); // 匹配关键字、运算符、标识符、字符串值、括号 Pattern pattern = Pattern.compile("(AND|OR|NOT|\\(|\\)|=|IN|'[^']+'|[a-zA-Z_][a-zA-Z0-9_]*)"); Matcher matcher = pattern.matcher(expr.replaceAll("\\s+", "")); while (matcher.find()) { String value = matcher.group(); if (value.equals("AND")) tokens.add(new Token(TokenType.AND, value)); else if (value.equals("OR")) tokens.add(new Token(TokenType.OR, value)); else if (value.equals("NOT")) tokens.add(new Token(TokenType.NOT, value)); else if (value.equals("(")) tokens.add(new Token(TokenType.LPAREN, value)); else if (value.equals(")")) tokens.add(new Token(TokenType.RPAREN, value)); else if (value.equals("=")) tokens.add(new Token(TokenType.EQ, value)); else if (value.equals("IN")) tokens.add(new Token(TokenType.IN, value)); else if (value.startsWith("'") && value.endsWith("'")) tokens.add(new Token(TokenType.VALUE, value.substring(1, value.length()-1))); else tokens.add(new Token(TokenType.IDENTIFIER, value)); } return tokens; } // 解析入口:处理OR连接的表达式 public Expression parse() { return parseExpression(); } private Expression parseExpression() { Expression expr = parseTerm(); while (pos < tokens.size() && tokens.get(pos).type == TokenType.OR) { pos++; expr = new OrExpression(expr, parseTerm()); } return expr; } // 处理AND连接的表达式 private Expression parseTerm() { Expression expr = parseFactor(); while (pos < tokens.size() && tokens.get(pos).type == TokenType.AND) { pos++; expr = new AndExpression(expr, parseFactor()); } return expr; } // 处理NOT、括号表达式或基础条件(优先级最高) private Expression parseFactor() { if (pos >= tokens.size()) throw new IllegalArgumentException("表达式格式错误"); Token token = tokens.get(pos); if (token.type == TokenType.NOT) { pos++; // 递归解析NOT后的因子,支持嵌套NOT(如NOT NOT(...)) Expression inner = parseFactor(); return new NotExpression(inner); } else if (token.type == TokenType.LPAREN) { pos++; Expression expr = parseExpression(); if (pos >= tokens.size() || tokens.get(pos).type != TokenType.RPAREN) { throw new IllegalArgumentException("括号不匹配"); } pos++; return expr; } else { return parseCondition(); } } // 解析基础条件语句 private Expression parseCondition() { if (pos >= tokens.size() || tokens.get(pos).type != TokenType.IDENTIFIER) { throw new IllegalArgumentException("预期字段名"); } String field = tokens.get(pos).value; pos++; if (pos >= tokens.size() || (tokens.get(pos).type != TokenType.EQ && tokens.get(pos).type != TokenType.IN)) { throw new IllegalArgumentException("预期运算符=或IN"); } ConditionExpression.Operator operator = tokens.get(pos).type == TokenType.EQ ? ConditionExpression.Operator.EQ : ConditionExpression.Operator.IN; pos++; if (pos >= tokens.size() || tokens.get(pos).type != TokenType.VALUE) { throw new IllegalArgumentException("预期值"); } Object value = tokens.get(pos).value; // 处理IN操作的多值(如'ADMIN,MANAGER'拆分为列表) if (operator == ConditionExpression.Operator.IN) { value = List.of(value.toString().split(",")); } pos++; return new ConditionExpression(field, operator, value); } // Token定义 private static class Token { enum TokenType {AND, OR, NOT, LPAREN, RPAREN, EQ, IN, IDENTIFIER, VALUE} final TokenType type; final String value; Token(TokenType type, String value) { this.type = type; this.value = value; } } }
3. 使用示例
import java.util.Map; public class ExpressionTest { public static void main(String[] args) { String exprStr = "EmployeeShift='General' AND NOT(EmployeeType='CONTRACT' OR Designation IN 'ADMIN')"; ExpressionParser parser = new ExpressionParser(exprStr); Expression expr = parser.parse(); // 测试数据1:满足条件 Map<String, Object> data1 = Map.of( "EmployeeShift", "General", "EmployeeType", "FULLTIME", "Designation", "ENGINEER" ); System.out.println(expr.evaluate(data1)); // 输出true // 测试数据2:不满足条件(EmployeeType为CONTRACT) Map<String, Object> data2 = Map.of( "EmployeeShift", "General", "EmployeeType", "CONTRACT", "Designation", "ENGINEER" ); System.out.println(expr.evaluate(data2)); // 输出false } }
关键说明
- 优先级保障:通过递归下降的层级划分(expression→term→factor),确保
NOT优先级最高,AND次之,OR最低,符合常规逻辑运算规则。 - 扩展性:若需支持
IN操作的多值列表(如Designation IN ('ADMIN','MANAGER')),可修改词法规则,识别括号包裹的多值集合。 - 错误处理:示例包含基础的格式校验,实际使用可根据需求增强异常提示和边界场景处理。
内容的提问来源于stack exchange,提问作者User1512
相关产品推荐
相关产品推荐

