1. XOR函数
XOR 函数可返回所有参数的异或值。异或的含义是:两个逻辑值相同,返回 false,两个逻辑值不同,则返回 true。
2. 函数用法
XOR(logical1,logical2, …)
3. 函数示例
如,判断两个答案值是否一致时,可设置公式为
XOR(答案1<90,答案2<90),答案一致时返回 false,不一致时返回 true。
4. 代码实战
首先我们在function包下创建logic包,在logic包下创建XorFunction类,代码如下:
package com.ql.util.express.self.combat.function.logic;import cn.hutool.core.util.ObjectUtil;
import com.ql.util.express.ArraySwap;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.self.combat.exception.FormulaException;/*** 类描述:XOR函数** @author admin* @version 1.0.0* @date 2023/11/21 17:13*/
public class XorFunction extends OperatorBase {public XorFunction(String name) {this.name = name;}@Overridepublic OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception {if (list.length < 2) {throw new FormulaException("\"" + this.aliasName + "\"操作至少要两个操作数");}OperateData rst = null;// 1. tj1 tj2 tj3 tj4 tj5OperateData flag = null;if (list.length == 2) {Object zero = list.get(0).getobject(parent);Object one = list.get(1).getobject(parent);if (ObjectUtil.equal(zero,one)) { //rst = new OperateData(Boolean.FALSE,Boolean.class);} else {rst = new OperateData(Boolean.TRUE,Boolean.class);}} else {Object zero = list.get(0).getobject(parent);Object one = list.get(1).getobject(parent);if (ObjectUtil.equal(zero,one)) { //rst = new OperateData(Boolean.FALSE,Boolean.class);flag = rst;} else {rst = new OperateData(Boolean.TRUE,Boolean.class);flag = rst;}Boolean flagB = (Boolean)flag.getobject(parent);for (int i=2;i<list.length;i++) {OperateData tmp = (OperateData)list.get(i);Boolean tmpB = (Boolean)tmp.getobject(parent);if (ObjectUtil.equal(tmpB,flagB)) {flag = new OperateData(Boolean.FALSE,Boolean.class);flagB = (Boolean)flag.getobject(parent);rst = flag;} else {flag = new OperateData(Boolean.TRUE,Boolean.class);flagB = (Boolean)flag.getObject(parent);rst = flag;}}}return rst;}}
把XorFunction类注册到公式函数入口类中,代码如下:
package com.ql.util.express.self.combat.ext;import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressResourceLoader;
import com.ql.util.express.parse.NodeTypeManager;
import com.ql.util.express.self.combat.function.logic.AndFunction;
import com.ql.util.express.self.combat.function.logic.IfFunction;
import com.ql.util.express.self.combat.function.logic.IfsFunction;
import com.ql.util.express.self.combat.function.logic.XorFunction;/*** 类描述: 仿简道云公式函数实战入口类** @author admin* @version 1.0.0* @date 2023/11/21 15:29*/
public class FormulaRunner extends ExpressRunner {public FormulaRunner() {super();}public FormulaRunner(boolean isPrecise, boolean isTrace) {super(isPrecise,isTrace);}public FormulaRunner(boolean isPrecise, boolean isStrace, NodeTypeManager nodeTypeManager) {super(isPrecise,isStrace,nodeTypeManager);}public FormulaRunner(boolean isPrecise, boolean isTrace, IExpressResourceLoader iExpressResourceLoader, NodeTypeManager nodeTypeManager) {super(isPrecise,isTrace,iExpressResourceLoader,nodeTypeManager);}@Overridepublic void addSystemFunctions() {// ExpressRunner 的内部系统函数super.addSystemFunctions();// 扩展公式函数this.customFunction();}/**** 自定义公式函数*/public void customFunction() {// AND函数this.addFunction("AND",new AndFunction("AND"));// IF函数this.addFunction("IF",new IfFunction("IF"));// IFS函数this.addFunction("IFS",new IfsFunction("IFS"));// XOR函数this.addFunction("XOR",new XorFunction("XOR"));}
}
创建测试用例:
package com.ql.util.express.self.combat;import com.ql.util.express.DefaultContext;
import com.ql.util.express.self.combat.ext.FormulaRunner;
import org.junit.Test;/*** 类描述: 实战测试类** @author admin* @version 1.0.0* @date 2023/11/21 15:45*/
public class CombatTest {@Testpublic void XOR() throws Exception{FormulaRunner formulaRunner = new FormulaRunner(true,true);// 创建上下文DefaultContext<String, object> context = new DefaultContext<>();String express = "XOR(答案1>90,答案2<90)";context.put("答案1",95);context.put("答案2",80);Object object = formulaRunner.execute(express, context, null, true, true);System.out.println(object);}}
运行结果: