zoukankan      html  css  js  c++  java
  • Java 表达式解析(非原创)

    因项目需要,在网上找来一套表达式解析方法,由于原来的方法太过于零散,不利于移植,现在整理在同一文件内;

    文件中包含5个内部类,源码如下:

       1 import java.util.ArrayList;
       2 import java.util.Date;
       3 import java.util.List;
       4 import java.util.Stack;
       5 
       6 /**
       7  * @项目名称: sunson_pams
       8  * @类名称: FormulaUtils
       9  * @类描述: 非原创(慎用)
      10  * @创建人: 唐泽齐
      11  * @创建时间: 2017年12月15日 上午9:47:23
      12  * @修改人: 唐泽齐
      13  * @修改时间: 2017年12月15日 上午9:47:23
      14  * @修改备注:
      15  * @version: 1.0
      16  */
      17 public class FormulaUtils {
      18 
      19     /**
      20      * 表达式解析
      21      */
      22     public static ExpressionEvaluator ExpressionEvaluator;
      23     
      24     public FormulaUtils() {
      25         ExpressionEvaluator = new ExpressionEvaluator();
      26     };
      27     
      28     /**
      29      * 表达式各个字符节点的类型枚举类
      30      * 
      31      * @项目名称: sunson_pams
      32      * @类名称: ExpressionNodeType
      33      * @类描述:
      34      * @创建人: 唐泽齐
      35      * @创建时间: 2017年12月15日 上午9:49:48
      36      * @修改人: 唐泽齐
      37      * @修改时间: 2017年12月15日 上午9:49:48
      38      * @修改备注:
      39      * @version: 1.0
      40      */
      41     public enum ExpressionNodeType {
      42 
      43         Unknown, Plus, // +
      44         Subtract, /// -
      45         MultiPly, // *
      46         Divide, // /
      47         LParentheses, // (
      48         RParentheses, /// )
      49         Mod, // % (求模,取余)
      50         Power, // ^ (次幂)
      51         BitwiseAnd, /// & (按位与)
      52         BitwiseOr, /// | (按位或)
      53         And, // && (逻辑与)
      54         Or, /// || (逻辑或)
      55         Not, /// ! (逻辑非)
      56         Equal, /// == (相等)
      57         Unequal, /// != 或 <> (不等于)
      58         GT, /// > (大于)
      59         LT, /// < (小于)
      60         GTOrEqual, /// >= (大于等于)
      61         LTOrEqual, /// <= (小于等于)
      62         LShift, /// << (左移位)
      63         RShift, /// >> (右移位)
      64         Numeric, /// 数值,
      65         String, Date, Like, // 包含
      66         NotLike, // 不包含
      67         StartWith, // 已什么开始
      68         EndWith// 已什么结尾
      69 
      70     }
      71 
      72     /**
      73      * 存储表达式运算符或操作数的各个节点的类
      74      * 
      75      * @项目名称: sunson_pams
      76      * @类名称: ExpressionNode
      77      * @类描述:
      78      * @创建人: 唐泽齐
      79      * @创建时间: 2017年12月15日 上午9:50:50
      80      * @修改人: 唐泽齐
      81      * @修改时间: 2017年12月15日 上午9:50:50
      82      * @修改备注:
      83      * @version: 1.0
      84      */
      85     public static class ExpressionNode {
      86 
      87         private String value;
      88 
      89         private ExpressionNodeType type;
      90 
      91         private int pri;
      92 
      93         private ExpressionNode unitaryNode;
      94 
      95         private Object numeric;
      96 
      97         /**
      98          * 
      99          * @param value
     100          *            操作数或运算符
     101          */
     102         public ExpressionNode(String value) {
     103             this.value = value;
     104             this.type = parseNodeType(value);
     105             this.pri = getNodeTypePRI(this.type);
     106             this.numeric = null;
     107         }
     108 
     109         public Object getNumeric() {
     110             if (this.numeric == null) {
     111 
     112                 if ((this.type == ExpressionNodeType.String) || (this.type == ExpressionNodeType.Date)) {
     113                     return this.value;
     114                 }
     115 
     116                 if (this.type != ExpressionNodeType.Numeric) {
     117                     return 0;
     118                 }
     119                 Double num = new Double(this.value);
     120                 if (this.unitaryNode != null && this.unitaryNode.type == ExpressionNodeType.Subtract) {
     121                     num = 0 - num;
     122                 }
     123                 this.numeric = num;
     124             }
     125             return numeric;
     126         }
     127 
     128         public void setNumeric(Object numeric) {
     129             this.numeric = numeric;
     130             this.value = this.numeric.toString();
     131         }
     132 
     133         /**
     134          * 设置或返回与当前节点相关联的一元操作符节点
     135          * 
     136          * @param unitaryNode
     137          */
     138         public void setUnitaryNode(ExpressionNode unitaryNode) {
     139             this.unitaryNode = unitaryNode;
     140         }
     141 
     142         /**
     143          * 解析节点类型
     144          * 
     145          * @param value
     146          * @return
     147          */
     148         private ExpressionNodeType parseNodeType(String value) {
     149             if (StringUtils.isEmpty(value)) {
     150                 return ExpressionNodeType.Unknown;
     151             }
     152             switch (value) {
     153             case "+":
     154                 return ExpressionNodeType.Plus;
     155             case "-":
     156                 return ExpressionNodeType.Subtract;
     157             case "*":
     158                 return ExpressionNodeType.MultiPly;
     159             case "/":
     160                 return ExpressionNodeType.Divide;
     161             case "%":
     162                 return ExpressionNodeType.Mod;
     163             case "^":
     164                 return ExpressionNodeType.Power;
     165             case "(":
     166                 return ExpressionNodeType.LParentheses;
     167             case ")":
     168                 return ExpressionNodeType.RParentheses;
     169             case "&":
     170                 return ExpressionNodeType.BitwiseAnd;
     171             case "|":
     172                 return ExpressionNodeType.BitwiseOr;
     173             case "&&":
     174             case "<并且>":
     175             case "并且":
     176                 return ExpressionNodeType.And;
     177             case "||":
     178             case "<或者>":
     179             case "或者":
     180                 return ExpressionNodeType.Or;
     181             case "!":
     182                 return ExpressionNodeType.Not;
     183             case "==":
     184             case "=":
     185                 return ExpressionNodeType.Equal;
     186             case "!=":
     187             case "<>":
     188             case "≠":
     189                 return ExpressionNodeType.Unequal;
     190             case ">":
     191                 return ExpressionNodeType.GT;
     192             case "<":
     193                 return ExpressionNodeType.LT;
     194             case ">=":
     195             case "≥":
     196                 return ExpressionNodeType.GTOrEqual;
     197             case "<=":
     198             case "≤":
     199                 return ExpressionNodeType.LTOrEqual;
     200             case "<<":
     201                 return ExpressionNodeType.LShift;
     202             case ">>":
     203                 return ExpressionNodeType.RShift;
     204             case "@":
     205             case "<包含>":
     206             case "包含":
     207                 return ExpressionNodeType.Like;
     208             case "!@":
     209             case "<不包含>":
     210             case "不包含":
     211                 return ExpressionNodeType.NotLike;
     212             case "!!$":
     213                 return ExpressionNodeType.StartWith;
     214             case "!!@":
     215                 return ExpressionNodeType.EndWith;
     216 
     217             }
     218             if (isNumerics(value)) {
     219                 return ExpressionNodeType.Numeric;
     220             }
     221             if (isDatetime(value)) {
     222                 return ExpressionNodeType.Date;
     223             }
     224             if (value.contains(""")) {
     225                 return ExpressionNodeType.String;
     226             }
     227             return ExpressionNodeType.Unknown;
     228         }
     229 
     230         /**
     231          * 获取各节点类型的优先级
     232          * 
     233          * @param nodeType
     234          * @return
     235          */
     236         private int getNodeTypePRI(ExpressionNodeType nodeType) {
     237             switch (nodeType) {
     238             case LParentheses:
     239             case RParentheses:
     240                 return 9;
     241             // 逻辑非是一元操作符,所以其优先级较高
     242             case Not:
     243                 return 8;
     244             case Mod:
     245                 return 7;
     246             case MultiPly:
     247             case Divide:
     248             case Power:
     249                 return 6;
     250             case Plus:
     251             case Subtract:
     252                 return 5;
     253             case LShift:
     254             case RShift:
     255                 return 4;
     256             case BitwiseAnd:
     257             case BitwiseOr:
     258                 return 3;
     259             case Equal:
     260             case Unequal:
     261             case GT:
     262             case LT:
     263             case GTOrEqual:
     264             case LTOrEqual:
     265             case Like:
     266             case NotLike:
     267             case StartWith:
     268             case EndWith:
     269                 return 2;
     270             case And:
     271             case Or:
     272                 return 1;
     273             default:
     274                 return 0;
     275             }
     276 
     277         }
     278 
     279         /**
     280          * 判断是否为数值
     281          * 
     282          * @param op
     283          * @return
     284          */
     285         public boolean isNumerics(String op) {
     286             return op.matches("^[\+\-]?(0|[1-9]\d*|[1-9]\d*\.\d+|0\.\d+)");
     287         }
     288 
     289         /**
     290          * 判断是否为日期
     291          * 
     292          * @param op
     293          * @return
     294          */
     295         public static boolean isDatetime(String op) {
     296             op = op.replace(""", "").trim();
     297             return op.matches("\d{4}\-\d{2}\-\d{2}(\s\d{2}\:\d{2}\:\d{2})?");
     298         }
     299 
     300         /**
     301          * 判断某个字符后是否需要更多的操作符
     302          * 
     303          * @param c
     304          * @return
     305          */
     306         public boolean needMoreOperator(char c) {
     307             switch (c) {
     308             case '&':
     309             case '|':
     310             case '=':
     311             case '!':
     312             case '>':
     313             case '<':
     314             case '.': // 小数点
     315                 return true;
     316             }
     317             // //数字则需要更多
     318             return Character.isDigit(c);
     319         }
     320 
     321         /**
     322          * 判断两个字符是否是同一类
     323          * 
     324          * @param c1
     325          * @param c2
     326          * @return
     327          */
     328         public boolean IsCongener(char c1, char c2) {
     329             if ((c1 == '(') || (c2 == '(')) {
     330                 return false;
     331             }
     332             if ((c1 == ')') || (c2 == ')')) {
     333                 return false;
     334             }
     335             if ((c1 == '"') || (c2 == '"')) {
     336                 return false;
     337             }
     338             if (Character.isDigit(c1) || (c1 == '.')) {
     339                 // c1为数字,则c2也为数字
     340                 return (Character.isDigit(c2) || (c2 == '.'));
     341             }
     342             return (!Character.isDigit(c2) && (c2 != '.'));
     343         }
     344 
     345         /**
     346          * 判断某个字符是否是空白字符
     347          * 
     348          * @param c
     349          * @return
     350          */
     351         public boolean IsWhileSpace(char c) {
     352             return c == ' ' || c == '	';
     353         }
     354 
     355         /**
     356          * 判断是否是一元操作符节点
     357          * 
     358          * @param nodeType
     359          * @return
     360          */
     361         public static boolean IsUnitaryNode(ExpressionNodeType nodeType) {
     362             return (nodeType == ExpressionNodeType.Plus || nodeType == ExpressionNodeType.Subtract);
     363         }
     364 
     365         public String getValue() {
     366             return value;
     367         }
     368 
     369         public void setValue(String value) {
     370             this.value = value;
     371         }
     372 
     373         public ExpressionNodeType getType() {
     374             return type;
     375         }
     376 
     377         public void setType(ExpressionNodeType type) {
     378             this.type = type;
     379         }
     380 
     381         public int getPri() {
     382             return pri;
     383         }
     384 
     385         public void setPri(int pri) {
     386             this.pri = pri;
     387         }
     388 
     389         public ExpressionNode getUnitaryNode() {
     390             return unitaryNode;
     391         }
     392     }
     393 
     394     /**
     395      * 表达式异常类
     396      * 
     397      * @项目名称: sunson_pams
     398      * @类名称: ExpressionException
     399      * @类描述:
     400      * @创建人: 唐泽齐
     401      * @创建时间: 2017年12月15日 上午9:52:13
     402      * @修改人: 唐泽齐
     403      * @修改时间: 2017年12月15日 上午9:52:13
     404      * @修改备注:
     405      * @version: 1.0
     406      */
     407     public static class ExpressionException extends RuntimeException {
     408 
     409         /**
     410          * 
     411          */
     412         private static final long serialVersionUID = 3136681292988750961L;
     413 
     414         public ExpressionException() {
     415             super();
     416         }
     417 
     418         public ExpressionException(String msg) {
     419             super(msg);
     420         }
     421 
     422         public ExpressionException(String msg, Throwable cause) {
     423             super(msg, cause);
     424         }
     425 
     426         public ExpressionException(Throwable cause) {
     427             super(cause);
     428         }
     429     }
     430 
     431     /**
     432      * 负责读取表达式生成ExpressionNode对象的类
     433      * 
     434      * @项目名称: sunson_pams
     435      * @类名称: ExpressionParser
     436      * @类描述:
     437      * @创建人: 唐泽齐
     438      * @创建时间: 2017年12月15日 上午9:52:59
     439      * @修改人: 唐泽齐
     440      * @修改时间: 2017年12月15日 上午9:52:59
     441      * @修改备注:
     442      * @version: 1.0
     443      */
     444     public static class ExpressionParser {
     445 
     446         // 当前分析的表达式
     447         private String expression;
     448 
     449         // 当前读取的位置
     450         private int position;
     451 
     452         public String getExpression() {
     453             return expression;
     454         }
     455 
     456         public void setExpression(String expression) {
     457             this.expression = expression;
     458         }
     459 
     460         public int getPosition() {
     461             return position;
     462         }
     463 
     464         public void setPosition(int position) {
     465             this.position = position;
     466         }
     467 
     468         public ExpressionParser(String expression) {
     469             this.expression = expression;
     470             this.position = 0;
     471         }
     472 
     473         /**
     474          * 读取下一个表达式节点,如果读取失败则返回null
     475          * 
     476          * @return
     477          */
     478         public ExpressionNode readNode() {
     479             ExpressionNode s = new ExpressionNode(null);
     480             // 空格的位置
     481             int whileSpacePos = -1;
     482             boolean flag = false;
     483             StringBuffer buffer = new StringBuffer(10);
     484             while (this.position < this.expression.length()) {
     485                 char c = this.expression.charAt(this.position);
     486                 if (c == '"') {
     487                     flag = !flag;
     488                     if (!flag) {
     489                         this.position++;
     490                         buffer.append(c);
     491                         break;
     492                     }
     493                     if (buffer.length() != 0) {
     494                         break;
     495                     }
     496                 }
     497                 if (flag) {
     498                     this.position++;
     499                     buffer.append(c);
     500                 } else {
     501                     if (s.IsWhileSpace(c)) {
     502                         if ((whileSpacePos >= 0) && ((this.position - whileSpacePos) > 1)) {
     503                             throw new ExpressionException(
     504                                     String.format("表达式"%s"在位置(%s)上的字符非法!", this.getExpression(), this.getPosition()));
     505                         }
     506                         if (buffer.length() == 0) {
     507                             whileSpacePos = -1;
     508                         } else {
     509                             whileSpacePos = this.position;
     510                         }
     511                         this.position++;
     512                         continue;
     513                     }
     514                     if ((buffer.length() == 0) || s.IsCongener(c, buffer.charAt(buffer.length() - 1))) {
     515                         this.position++;
     516                         buffer.append(c);
     517                     } else {
     518                         break;
     519                     }
     520                     if (!s.needMoreOperator(c)) {
     521                         break;
     522                     }
     523                 }
     524             }
     525             if (buffer.length() == 0) {
     526                 return null;
     527             }
     528             ExpressionNode node = new ExpressionNode(buffer.toString());
     529             if (node.getType() == ExpressionNodeType.Unknown) {
     530                 throw new ExpressionException(String.format("表达式"%s"在位置%s上的字符"%s"非法!", this.getExpression(),
     531                         this.getPosition() - node.getValue().length(), node.getValue()));
     532             }
     533             return node;
     534         }
     535 
     536     }
     537 
     538     /**
     539      * 解析公式并返回结果的类
     540      * 
     541      * @项目名称: sunson_pams
     542      * @类名称: ExpressionEvaluator
     543      * @类描述:
     544      * @创建人: 唐泽齐
     545      * @创建时间: 2017年12月15日 上午9:56:08
     546      * @修改人: 唐泽齐
     547      * @修改时间: 2017年12月15日 上午9:56:08
     548      * @修改备注:
     549      * @version: 1.0
     550      */
     551     public static class ExpressionEvaluator {
     552 
     553         private ExpressionEvaluator() {
     554 
     555         }
     556 
     557         /**
     558          * 将算术表达式转换为逆波兰表达式
     559          * 
     560          * @param expression
     561          *            要计算的表达式,如"1+2+3+4"
     562          * @return
     563          */
     564         private static  List<ExpressionNode> parseExpression(String expression) {
     565             if (StringUtils.isEmpty(expression)) {
     566                 return new ArrayList<ExpressionNode>();
     567             }
     568 
     569             List<ExpressionNode> listOperator = new ArrayList<ExpressionNode>(10);
     570             Stack<ExpressionNode> stackOperator = new Stack<ExpressionNode>();
     571 
     572             ExpressionParser expParser = new ExpressionParser(expression);
     573             ExpressionNode beforeExpNode = null; // 前一个节点
     574             ExpressionNode unitaryNode = null; // 一元操作符
     575             ExpressionNode expNode;
     576             // 是否需要操作数
     577             boolean requireOperand = false;
     578 
     579             while ((expNode = expParser.readNode()) != null) {
     580                 if ((expNode.getType() == ExpressionNodeType.Numeric)
     581                         || (expNode.getType() == ExpressionNodeType.String)
     582                         || (expNode.getType() == ExpressionNodeType.Date)) {
     583                     // 操作数, 直接加入后缀表达式中
     584                     if (unitaryNode != null) {
     585                         // 设置一元操作符节点
     586                         expNode.setUnitaryNode(unitaryNode);
     587                         unitaryNode = null;
     588                     }
     589 
     590                     listOperator.add(expNode);
     591                     requireOperand = false;
     592                     continue;
     593                 } else if (expNode.getType() == ExpressionNodeType.LParentheses) {
     594                     // 左括号, 直接加入操作符栈
     595                     stackOperator.push(expNode);
     596                     continue;
     597                 } else if (expNode.getType() == ExpressionNodeType.RParentheses) {
     598                     // 右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
     599                     ExpressionNode lpNode = null;
     600                     while (stackOperator.size() > 0) {
     601                         lpNode = stackOperator.pop();
     602                         if (lpNode.getType() == ExpressionNodeType.LParentheses)
     603                             break;
     604                         listOperator.add(lpNode);
     605                     }
     606                     if (lpNode == null || lpNode.getType() != ExpressionNodeType.LParentheses) {
     607                         throw new ExpressionException(String.format("在表达式"%s"中没有与在位置(%s)上")"匹配的"(%s)"字符!",expParser.getExpression(), expParser.getPosition()));
     608                     }
     609                 } else {
     610                     if (stackOperator.size() == 0) {
     611                         // 第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法
     612                         if (listOperator.size() == 0 && !(expNode.getType() == ExpressionNodeType.LParentheses
     613                                 || expNode.getType() == ExpressionNodeType.Not)) {
     614                             // 后缀表达式没有任何数据则判断是否是一元操作数
     615                             if (ExpressionNode.IsUnitaryNode(expNode.getType())) {
     616                                 unitaryNode = expNode;
     617                             } else {
     618                                 // 丢失操作数
     619                                 throw new ExpressionException(String.format("表达式"%s"在位置(%s)上缺少操作数!",
     620                                         expParser.getExpression(), expParser.getPosition()));
     621                             }
     622                         } else {
     623                             // 直接压入操作符栈
     624                             stackOperator.push(expNode);
     625                         }
     626                         requireOperand = true; // 下一个节点需要操作数
     627                         continue;
     628                     } else {
     629                         if (requireOperand) {
     630                             // 如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
     631                             if (ExpressionNode.IsUnitaryNode(expNode.getType()) && unitaryNode == null) {
     632                                 unitaryNode = expNode;
     633                             } else {
     634                                 // 丢失操作数
     635                                 throw new ExpressionException(String.format("表达式"%s"在位置({1})上缺少操作数!",
     636                                         expParser.getExpression(), expParser.getPosition()));
     637                             }
     638                         } else {
     639                             // 对前面的所有操作符进行优先级比较
     640                             do {
     641                                 // 取得上一次的操作符
     642                                 beforeExpNode = stackOperator.peek();
     643 
     644                                 // 如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中
     645                                 if (beforeExpNode.getType() != ExpressionNodeType.LParentheses
     646                                         && (beforeExpNode.getPri() - expNode.getPri()) >= 0) {
     647                                     listOperator.add(stackOperator.pop());
     648                                 } else {
     649                                     break;
     650                                 }
     651 
     652                             } while (stackOperator.size() > 0);
     653 
     654                             // 将操作符压入操作符栈
     655                             stackOperator.push(expNode);
     656                             requireOperand = true;
     657                         }
     658                     }
     659                 }
     660             }
     661 
     662             if (requireOperand) {
     663                 // 丢失操作数
     664                 throw new ExpressionException(
     665                         String.format("表达式"%s"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition()));
     666             }
     667             // 清空堆栈
     668             while (stackOperator.size() > 0) {
     669                 // 取得操作符
     670                 beforeExpNode = stackOperator.pop();
     671                 if (beforeExpNode.getType() == ExpressionNodeType.LParentheses) {
     672                     throw new ExpressionException(String.format("表达式"%s"中括号不匹配,丢失右括号!", expParser.getExpression(),
     673                             expParser.getPosition()));
     674                 }
     675                 listOperator.add(beforeExpNode);
     676             }
     677 
     678             return listOperator;
     679         }
     680 
     681         /**
     682          * 对逆波兰表达式进行计算
     683          * 
     684          * @param nodes
     685          * @return
     686          */
     687         @SuppressWarnings({ "rawtypes", "unchecked", "incomplete-switch" })
     688         private static  Object CalcExpression(List<ExpressionNode> nodes) {
     689             if (nodes == null || nodes.size() == 0)
     690                 return null;
     691 
     692             if (nodes.size() > 1) {
     693                 int index = 0;
     694                 // 储存数据
     695                 ArrayList values = new ArrayList();
     696                 while (index < nodes.size()) {
     697                     ExpressionNode node = nodes.get(index);
     698 
     699                     switch (node.getType()) {
     700                     // 如果是数字,则将值存入 values 中
     701                     case Numeric:
     702                     case String:
     703                     case Date:
     704                         values.add(node.getNumeric());
     705                         index++;
     706                         break;
     707                     default:
     708                         // 二元表达式,需要二个参数, 如果是Not的话,则只要一个参数
     709                         int paramCount = 2;
     710                         if (node.getType() == ExpressionNodeType.Not)
     711                             paramCount = 1;
     712                         // 计算操作数的值
     713                         if (values.size() < paramCount) {
     714                             throw new ExpressionException("缺少操作数");
     715                         }
     716                         // 传入参数
     717                         Object[] data = new Object[paramCount];
     718                         for (int i = 0; i < paramCount; i++) {
     719                             data[i] = values.get(index - paramCount + i);
     720                         }
     721                         // 将计算结果再存入当前节点
     722                         node.setNumeric(calculate(node.getType(), data));
     723                         node.setType(ExpressionNodeType.Numeric);
     724                         // 将操作数节点删除
     725                         for (int i = 0; i < paramCount; i++) {
     726                             nodes.remove(index - i - 1);
     727                             values.remove(index - i - 1);
     728                         }
     729                         index -= paramCount;
     730                         break;
     731                     }
     732 
     733                 }
     734             }
     735 
     736             if (nodes.size() != 1) {
     737                 throw new ExpressionException("缺少操作符或操作数");
     738             }
     739             switch (nodes.get(0).getType()) {
     740             case Numeric:
     741                 return nodes.get(0).getNumeric();
     742 
     743             case String:
     744             case Date:
     745                 return nodes.get(0).getNumeric().toString().replace(""", "");
     746             }
     747             throw new ExpressionException("缺少操作数");
     748         }
     749 
     750         /**
     751          * 计算节点的值
     752          * 
     753          * @param nodeType
     754          *            节点的类型
     755          * @param data
     756          *            要计算的值,有可能是两位或一位数
     757          * @return
     758          */
     759         @SuppressWarnings("incomplete-switch")
     760         private static  Object calculate(ExpressionNodeType nodeType, Object[] data) {
     761             double d1, d2;
     762             boolean b1, b2;
     763             Date time1, time2;
     764             Object obj1 = data[0];
     765             Object obj2 = data[1];
     766             String str1 = obj1.toString();
     767             String str2 = obj2.toString();
     768 
     769             boolean dateflag = ExpressionNode.isDatetime(str1) || ExpressionNode.isDatetime(str2);
     770             boolean strflag = str1.contains(""") || str2.contains(""");
     771             str1 = str1.replace(""", "");
     772             str2 = str2.replace(""", "");
     773 
     774             switch (nodeType) {
     775             case Plus:
     776                 if (!strflag) {
     777                     d1 = ConvertToDecimal(obj1);
     778                     d2 = ConvertToDecimal(obj2);
     779                     return (d1 + d2);
     780                 }
     781                 return new StringBuffer(str1 + str2).toString();
     782             case Subtract:
     783                 d1 = ConvertToDecimal(obj1);
     784                 d2 = ConvertToDecimal(obj2);
     785                 return d1 - d2;
     786             case MultiPly:
     787                 d1 = ConvertToDecimal(obj1);
     788                 d2 = ConvertToDecimal(obj2);
     789                 return d1 * d2;
     790             case Divide:
     791                 d1 = ConvertToDecimal(obj1);
     792                 d2 = ConvertToDecimal(obj2);
     793                 if (d2 == 0)
     794                     throw new RuntimeException();
     795                 return d1 / d2;
     796             case Power:
     797                 d1 = ConvertToDecimal(obj1);
     798                 d2 = ConvertToDecimal(obj2);
     799                 return Math.pow((double) d1, (double) d2);
     800             case Mod:
     801                 d1 = ConvertToDecimal(obj1);
     802                 d2 = ConvertToDecimal(obj2);
     803                 if (d2 == 0)
     804                     throw new RuntimeException();
     805                 return d1 % d2;
     806             case BitwiseAnd:
     807                 d1 = ConvertToDecimal(obj1);
     808                 d2 = ConvertToDecimal(obj2);
     809                 return (int) d1 & (int) d2;
     810             case BitwiseOr:
     811                 d1 = ConvertToDecimal(obj1);
     812                 d2 = ConvertToDecimal(obj2);
     813                 return (int) d1 | (int) d2;
     814             case And:
     815                 b1 = ConvertToBool(obj1);
     816                 b2 = ConvertToBool(obj2);
     817                 return b1 && b2;
     818             case Or:
     819                 b1 = ConvertToBool(obj1);
     820                 b2 = ConvertToBool(obj2);
     821                 return b1 || b2;
     822             case Not:
     823                 b1 = ConvertToBool(obj1);
     824                 return !b1;
     825             case Equal:
     826                 if (!dateflag) {
     827                     if (strflag) {
     828                         return str1.equals(str2);
     829                     }
     830                     d1 = ConvertToDecimal(obj1);
     831                     d2 = ConvertToDecimal(obj2);
     832                     return (d1 == d2);
     833                 }
     834                 time1 = DateUtils.parseDate(str1);
     835                 time2 = DateUtils.parseDate(str2);
     836 
     837                 return (time1.getTime() == time2.getTime());
     838             case Unequal:
     839                 if (!dateflag) {
     840                     if (strflag) {
     841                         return (!str1.equals(str2));
     842                     }
     843                     d1 = ConvertToDecimal(obj1);
     844                     d2 = ConvertToDecimal(obj2);
     845                     return (d1 != d2);
     846                 }
     847                 time1 = DateUtils.parseDate(str1);
     848                 time2 = DateUtils.parseDate(str2);
     849 
     850                 return (time1.getTime() != time2.getTime());
     851             case GT:
     852 
     853                 if (!dateflag) {
     854                     d1 = ConvertToDecimal(obj1);
     855                     d2 = ConvertToDecimal(obj2);
     856                     return (d1 > d2);
     857                 }
     858                 time1 = DateUtils.parseDate(str1);
     859                 time2 = DateUtils.parseDate(str2);
     860                 return (time1.getTime() > time2.getTime());
     861 
     862             case LT:
     863 
     864                 if (!dateflag) {
     865                     d1 = ConvertToDecimal(obj1);
     866                     d2 = ConvertToDecimal(obj2);
     867                     return (d1 < d2);
     868                 }
     869                 time1 = DateUtils.parseDate(str1);
     870                 time2 = DateUtils.parseDate(str2);
     871                 return (time1.getTime() < time2.getTime());
     872 
     873             case GTOrEqual:
     874 
     875                 if (!dateflag) {
     876                     d1 = ConvertToDecimal(obj1);
     877                     d2 = ConvertToDecimal(obj2);
     878                     return (d1 >= d2);
     879                 }
     880                 time1 = DateUtils.parseDate(str1);
     881                 time2 = DateUtils.parseDate(str2);
     882                 return (time1.getTime() >= time2.getTime());
     883 
     884             case LTOrEqual:
     885                 if (!dateflag) {
     886                     d1 = ConvertToDecimal(obj1);
     887                     d2 = ConvertToDecimal(obj2);
     888                     return (d1 <= d2);
     889                 }
     890                 time1 = DateUtils.parseDate(str1);
     891                 time2 = DateUtils.parseDate(str2);
     892                 return (time1.getTime() <= time2.getTime());
     893             case LShift:
     894                 d1 = ConvertToDecimal(obj1);
     895                 d2 = ConvertToDecimal(obj2);
     896                 return (long) d1 << (int) d2;
     897 
     898             case RShift:
     899                 d1 = ConvertToDecimal(obj1);
     900                 d2 = ConvertToDecimal(obj2);
     901                 return (long) d1 >> (int) d2;
     902             case Like:
     903                 if (!strflag) {
     904                     return false;
     905                 }
     906                 return str1.contains(str2);
     907             case NotLike:
     908                 if (!strflag) {
     909                     return false;
     910                 }
     911                 return !str1.contains(str2);
     912             case StartWith:
     913                 if (!strflag) {
     914                     return false;
     915                 }
     916                 return str1.startsWith(str2);
     917             case EndWith:
     918                 if (!strflag) {
     919                     return false;
     920                 }
     921                 return str1.endsWith(str2);
     922             }
     923 
     924             return 0;
     925         }
     926 
     927         /**
     928          * 某个值转换为bool值
     929          * 
     930          * @param value
     931          * @return
     932          */
     933         private static  Boolean ConvertToBool(Object value) {
     934             if (value instanceof Boolean) {
     935                 return (Boolean) value;
     936             } else {
     937                 return value != null;
     938             }
     939         }
     940 
     941         /**
     942          * 将某个值转换为decimal值
     943          * 
     944          * @param value
     945          * @return
     946          */
     947         private static  Double ConvertToDecimal(Object value) {
     948             if (value instanceof Boolean) {
     949                 return ((Boolean) value ? 1d : 0d);
     950             } else {
     951                 return Double.parseDouble(value.toString());
     952             }
     953         }
     954 
     955         /**
     956          * 
     957          * @param expression
     958          *            要计算的表达式,如"1+2+3+4"
     959          * @return 返回计算结果,如果带有逻辑运算符则返回true/false,否则返回数值
     960          */
     961         public Object eval(String expression) {
     962             return CalcExpression(parseExpression(expression));
     963         }
     964 
     965         public  Object evalThreeOperand(String expression) {
     966             int index = expression.indexOf("?");
     967             if (index > -1) {
     968                 String str = expression.substring(0, index);
     969                 String str2 = expression.substring(index + 1);
     970                 index = str2.indexOf(":");
     971 
     972                 if (Boolean.parseBoolean((CalcExpression(parseExpression(str))).toString())) {
     973                     return eval(str2.substring(0, index));
     974                 }
     975                 return eval(str2.substring(index + 1));
     976             }
     977             return CalcExpression(parseExpression(expression));
     978         }
     979 
     980     }
     981 
     982 //    /**
     983 //     * 测试
     984 //     * 
     985 //     * @方法名:main
     986 //     * @参数 @param args
     987 //     * @返回类型 void
     988 //     */
     989 //    public static void main(String[] args) {
     990 //        String s1 = "1+2+3+4";
     991 //        System.out.println(ExpressionEvaluator.eval(s1));
     992 //
     993 //        String s2 = "(20 - 6) < 3";
     994 //        System.out.println(ExpressionEvaluator.eval(s2));
     995 //
     996 //        String s3 = "(3 + 1) == 4 && 5 > (2 + 3)";
     997 //        System.out.println(ExpressionEvaluator.eval(s3));
     998 //
     999 //        String s4 = ""hello" == "hello" && 3 != 4";
    1000 //        System.out.println(ExpressionEvaluator.eval(s4));
    1001 //
    1002 //        String s5 = ""helloworld" @ "hello" &&  "helloworld" !@ "word" ";
    1003 //        System.out.println(ExpressionEvaluator.eval(s5));
    1004 //
    1005 //    }
    1006 
    1007 }
  • 相关阅读:
    类定义(课下选做)
    结对项目第一周
    迭代和JDB
    JAVA 第五周学习总结
    JAVA 第四周学习总结
    JAVA 第三周学习总结
    springcloud-provider-consumer-register
    springcloud-eureka
    springBoot-打包
    spring-Scheduler
  • 原文地址:https://www.cnblogs.com/tangzeqi/p/8046732.html
Copyright © 2011-2022 走看看