转载内容:
今天遇到了一个需要将数据库中保存的表达式,替换其中的字符,并计算出值,java是不能直接计算的例如:
double d = (3+5-(2-4)*2)/24;没有问题
但是:遇到 "(3+5-(2-4)*2)/24" 字符串的格式,就不能使用了
java是无法解决,但是javaScript中有一个eval函数是可以执行的,所以,可以通过其他途径执行javaScript就可以做到,而ScriptEngine是java的一个javaScript实现类,所以就找到了方法,详细方法见下
public class MapJ {
private String key; // 替换的编号
private String value; // 值
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public MapJ(String key, String value) {
super();
this.key = key;
this.value = value;
}
public MapJ() {
super();
}
}
// 实现类
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JavaScript {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
public Double getMathValue(List<MapJ> map,String option) {
double d = 0;
try {
for (int i=0; i<map.size(); i++) {
MapJ mapj = map.get(i);
option = option.replaceAll(mapj.getKey(), mapj.getValue());
}
Object o = engine.eval(option);
d = Double.parseDouble(o.toString());
} catch (ScriptException e) {
System.out.println("无法识别表达式");
return null;
}
return d;
}
}
public class JavaScriptTest {
public static void main(String[] args) {
String sbt = "(B+D-(A-C)*A)/F";
List<MapJ> all = new ArrayList<MapJ>();
all.add(new MapJ("A","2"));
all.add(new MapJ("B","3"));
all.add(new MapJ("C","4"));
all.add(new MapJ("D","5"));
all.add(new MapJ("F","24"));
JavaScript js = new JavaScript();
Double d = js.getMathValue(all, sbt);
if (d == null) {
System.out.println("无法计算这个表达式");
} else {
System.out.println(d*100+"%");
}
}
}
通过以上的方法即可实现此方法。
50.0%
切换为:结合StringSubstitutor 替换占位符
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JavaScript {
public static final ScriptEngineManager SCRIPT_ENGINE_MANAGER = new ScriptEngineManager();
public static final ScriptEngine ENGINE;
static {
ENGINE = SCRIPT_ENGINE_MANAGER.getEngineByName("JavaScript");
}
public Double getMathValue(String option) {
double d;
try {
d = (double) ENGINE.eval(option);
// ScirptEngine.eval() 方法,执行表达式,可以判断表达式对错,返回true or false
if ("true".equals(ENGINE.eval(d + ">0.4").toString())) {
System.out.println("结果比0.4大");
}
} catch (ScriptException e) {
System.out.println("无法识别表达式");
return null;
}
return d;
}
}
public class TestMain {
public static void main(String[] args) {
Map valuesMap = new HashMap(5);
valuesMap.put("A", "2");
valuesMap.put("B", "3");
valuesMap.put("C", "4");
valuesMap.put("D", "5");
valuesMap.put("F", "24");
// 修改
String sbt = "(${B}+${D}-(${A}-${C})*${A})/${F}";
// 结合StringSubstitutor 替换占位符
StrSubstitutor sub = new StrSubstitutor(valuesMap);
// 自动根据valuesMap的key,将value替换到表达式中
String resolvedString = sub.replace(sbt);
JavaScript js = new JavaScript();
Double d = js.getMathValue(resolvedString);
if (d == null) {
System.out.println("无法计算这个表达式");
} else {
System.out.println(d * 100 + "%");
}
}
}
结果比0.4大
50.0%
Apache commons StringSubstitutor 替换占位符介绍:https://blog.youkuaiyun.com/weixin_41888813/article/details/90481607
参考来源: