java中的string语句_(JAVA)String类型的逻辑语句编译

项目中遇到了动态配置条件触发相应事件的需求,需要根据String类型的逻辑语句,以及动态获取的数据,计算数据对应的结果,java实现。解决思路及代码实现如下,有需要的同学请自取。

一、需求提取

根据需求,抛开业务部分,我们可以将需求简化成以下核心逻辑。输入String类型的逻辑字符串,支持的逻辑符号包括 > ,  < , <= ,>= ,== ,() 。 例如: "(a>1&&b<2)||(c>=3&&d==4)" ,动态解析该字符串,并对输入的任意json类数据做出正确的逻辑判断。如{“b” : 10 , "a" : 9 , "c":"error" }。

二、设计思路

因为每一个最小的逻辑点。如 “a>1” 都只有两个结果:成功或者失败,并且成功或者失败后,往往需要执行下一个逻辑,所以该逻辑模型可以转换成一个二叉树的结构。据此我们先画出  "(a>1&&b<2)||(c>=3&&d==4)"  的逻辑图

124d7df6259e23f6d9b74f0c85f7b20f.png

每一个逻辑根据成功或者失败,指向了另外的逻辑,或者指向了最终结果,这里我们可以把指向的这个操作等价成指针,该指针指向了另外一个逻辑实体,或者指向了最终结果,又因为java中的指针,或者说引用都是需要事先指定数据类型的,如果我们使用逻辑实体和布尔类型的两种数据对象,那我们就只能将引用声明为两种数据对象的统一父类Object。但是因为Object在使用过程中涉及到了类型的判断及转化,很不方便,所以我们直接使用逻辑实体表示 逻辑,用 null表示可以直接返回最终结果。

除了两个引用以外,该逻辑实体应该还包括三个关键字,三个关键字有数据对应的key值"a" , 数据对应的逻辑符号 “>”,数据对应的阈值"1"。

据此,我们可以确定该逻辑实体的五个字段 ,建出以下实体

1 public classLogic {2 //值对应的key值

3 privateString key;4 //逻辑符号 包括 > < >= <= ==

5 private doublesymbol;6 //阈值

7 private doublevalue;8 //成功是返回,为null时表示最终结果为true

9 privateLogic sucLogic;10 //失败是返回,为null时表示最终结果为false

11 privateLogic failLogic;12

13 //后面会用到的两个方法14 //在logic树的每一层失败分支子树上都加一个成功时调用的对象

15 public voidsetSucLogicEveryFail(Logic logic){16 Logic logic1 = this;17 while (true){18 logic1.setSucLogic( logic );19 if ( logic1.getFailLogic != null){20 logic1 =logic1.getFailLogic();21 }else{22 return;23 }24 }25 }26 //在logic树的每一层成功分支上子树上都加一个失败时调用的对象

27 public voidsetFailLogicEverySuc(Logic logic){28 Logic logic1 = this;29 while (true){30 logic1.setFailLogic( logic );31 if ( logic1.getSucLogic != null){32 logic1 =logic1.getSucLogic ();33 }else{34 return;35 }36 }37 }38 }

使用该实体的原因如下:

1) 可以很清楚的表明逻辑关系

2) 增加了处理时的开销,减少了使用时的开销,更好的支持大批量的数据判断

三、编码实现

1. 根据string生成Logic对象的代码

1 public classCreateLogic {2

3 private static String[] symbol = {">=","<=",">","=","","=="};5

6 public static voidmain(String[] args) {7 CreateLogic createLogic = newCreateLogic();8 Logic logic = createLogic.handleContentLogic("(a>1&&b<2)||(c>=3&&d==4)");9 System.out.println( logic);10 }11

12 privateLogic handleContentLogic(String content) {13 //1.去除掉首位的无效括号

14 content = this.removeNoUseContent( content );15 //2.将content拆成小的逻辑块。

16 List blockContents = new ArrayList<>();17 int point = 0;18 int flag = 0;19 for (int i = 0; i < content.length(); i++) {20 char c =content.charAt(i);21 if( '(' ==c){22 flag++;23 continue;24 }else if( ')' ==c){25 flag--;26 if( flag == 0){27 blockContents.add( content.substring( point , i + 1) );28 point = i + 1;29 }30 }else if( flag == 0 && ('|' == content.charAt(i) || '&' ==content.charAt(i)) ){31 if( i - point > 1){32 blockContents.add( content.substring( point , i ) );33 point =i;34 }35 }else if( i == content.length() - 1){36 blockContents.add( content.substring( point , i + 1) );37 }38 }39 //3.遍历获取最终逻辑

40 Logic logic = null;41 for (int i = 0; i < blockContents.size(); i++) {42 String blockContent =blockContents.get(i);43 if( blockContent.startsWith("||(") ){44 Logic logic1 = this.handleContentLogic(blockContent.substring(2));45 logic.setFailLogicEverySuc(logic1);46 }else if( blockContent.startsWith("&&(") ){47 Logic logic1 = this.handleContentLogic(blockContent.substring(2));48 logic.setSucLogicEveryFail(logic1);49 }else if( blockContent.startsWith("&&") ) {50 Logic logic1 = this.getLogicBySimpleContent(blockContent.substring(2));51 logic1.setSucLogicEveryFail(logic);52 logic =logic1;53 }else if( blockContent.startsWith("||") ) {54 Logic logic1 = this.getLogicBySimpleContent(blockContent.substring(2));55 logic1.setFailLogicEverySuc(logic);56 logic =logic1;57 }else{58 logic = this.getLogicBySimpleContent(blockContent);59 }60 }61 returnlogic;62 }63

64 /**

65 * 去除掉首位的无效括号66 *@paramcontent67 *@return

68 */

69 publicString removeNoUseContent( String content ){70 List list = new ArrayList<>(Arrays.asList(content.split(""))) ;71 //1.首位的小括号为无效的小括号,先去除掉

72 int flag1 = 0;73 int flag2 = 0;74 while (true){75 if( "(".equals(list.get(0) )){76 flag1++;77 list.remove(0);78 }else{79 break;80 }81 }82 if( flag1 > 0){83 for (int i = 0; i < list.size(); i++) {84 if( flag1 == 0){85 break;86 }87 if( "(".equals(list.get(i) ) ){88 flag2++;89 }else if( ")".equals( list.get(i) ) ){90 if(flag2 > 0){91 flag2--;92 continue;93 }else{94 flag1--;95 list.remove(i);96 i--;97 }98 }99 }100 }101 returnStringUtils.join(list.toArray());102 }103

104 /**

105 * 简单的逻辑文本直接转换成一个逻辑实体106 *@paramblockContent107 *@return

108 */

109 privateLogic getLogicBySimpleContent(String blockContent) {110 Logic logic = newLogic();111 for (int i = 0; i < symbol.length; i++) {112 if( blockContent.indexOf( symbol[i] ) != -1){113 String value1 = blockContent.substring(0, blockContent.indexOf( symbol[i] ));114 String value2 = blockContent.substring( blockContent.indexOf( symbol[i] ) +symbol[i].length());115 try{116 double b =Double.valueOf(value2);117 logic.setKey(value1);118 logic.setValue(b);119 logic.setSymbol(symbol[i]);120 }catch(Exception e){121 double b =Double.valueOf(value1);122 logic.setKey(value2);123 logic.setValue(b);124 logic.setSymbol(backSymbol[i]);125 }126 returnlogic;127 }128 }129 returnlogic;130 }131 }

2. 根据Logic和json判断最终结果

1 public classHandleLogic {2 /**

3 * 根据逻辑树,递归获取最终的逻辑结果s4 */

5 public booleanhandleMessageByLogicCore(Logic logic , JSONObject object ) {6 boolean bool = false;7 String key =logic.getKey();8 if( object.get(key) == null){9 return this.getLogicByResult(logic , bool , object);10 }11 double value =logic.getValue();12 double realValue =object.getDoubleValue( key );13 switch( logic.getSymbol() ){14 case ">=":15 bool = realValue >=value;16 break;17 case "<=":18 bool = realValue <=value;19 break;20 case "==":21 bool = realValue ==value;22 break;23 case "":27 bool = realValue >value;28 break;29 }30 return this.getLogicByResult(logic , bool , object);31 }32

33 /**

34 * 根据逻辑的结果,获取逻辑的成功/失败的子逻辑树,不存在则直接返回成功/失败35 *@paramlogic 当前逻辑树36 *@paramb 当前逻辑树的执行结果37 *@paramobject 当前逻辑树的处理对象38 *@return

39 */

40 private boolean getLogicByResult(Logic logic, booleanb, JSONObject object) {41 if( b ){42 if( logic.getSucLogic() == null){43 return true;44 }else{45 returnhandleMessageByLogicCore( logic.getSucLogic() , object );46 }47 }else{48 if( logic.getFailLogic() == null){49 return false;50 }else{51 returnhandleMessageByLogicCore( logic.getFailLogic() , object );52 }53 }54 }55 }

以上就是逻辑语句编译的总结,原创不易,转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值