Java通过String类型计算公式,算出结果值
需求:(通过数据库取出计算公式,在获取数据值计算结果)

实现方法(独立方法,可以直接使用):
static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
/* 公式格式和数据格式
countmode = "R=(M/N)×100%;M=A+B;N=C+D";
map.put("A", "2");
map.put("B", "1");
map.put("C", "2");
map.put("D", "1");
*/
public String calculation(String countmode, Map map) {
//判断是否存在公式
if (StringUtils.isBlank(countmode)) {
return "";
}
//结果值
String vaule = "";
//判断公式是否只是简单的=值
char[] chars = countmode.toCharArray();
if (chars.length == 3) {
for (Object key : map.keySet()) {
Object a = map.get(key);
vaule = String.valueOf(a);
}
return vaule;
}
//判断公式中是否存在百分号
boolean symbol = false;
//判断公式中是否存在冒号
boolean colon = false;
String colonVaule = "";
//处理特殊符号
countmode = countmode.replaceAll("(", "(");
countmode = countmode.replaceAll(")", ")");
countmode = countmode.replaceAll("×", "*");
countmode = countmode.replaceAll("\\{", "[");
countmode = countmode.replaceAll("}", "]");
String regEx = "[%]";
Pattern compile = Pattern.compile(regEx);
Matcher matcher = compile.matcher(countmode);
if (matcher.find()) {
symbol = true;
countmode = countmode.replaceAll("%", "");
}
//多个公式返回数组
String[] countmodes = countmode.split(";");
try {
//判断是否需要多次计算
if (countmodes.length == 1) {
//获取计算公式
String equalationRight = countmode.split("=")[1];
//判断公式中是否存在结果之间的互比
String regExs = "[:]";
Pattern compiles = Pattern.compile(regExs);
Matcher matchers = compiles.matcher(countmode);
if (matchers.find()) {
colon = true;
colonVaule = equalationRight.split(":")[0];
equalationRight = equalationRight.split(":")[1];
}
//获取计算公式字母,用于取值
char[] split = equalationRight.replaceAll("[^A-Za-z]", "").toCharArray();
for (char s : split) {
String key = String.valueOf(s);
String val = DwuObject.valString(key, map);
//值为空则设置为0
if (StringUtils.isBlank(val)) {
val = "0";
}
//将值替换到公式中
equalationRight = equalationRight.replaceAll(key, val);
}
Object eval = jse.eval(equalationRight);
vaule = String.valueOf(eval);
//当被除数、除数都为0的情况和被除数为0的情况直接返回0
if (vaule.equals("NaN") || vaule.equals("Infinity")) {
return "0";
}
if (symbol) {
vaule = vaule + "%";
}
if (colon) {
vaule = colonVaule + ":" + vaule;
}
} else {
for (int i = countmodes.length - 1; i >= 0; i--) {
//计算结果代表字母,用于多次计算取值
String equalationKey = countmodes[i].split("=")[0];
//获取计算公式
String equalationRight = countmodes[i].split("=")[1];
//获取计算公式字母,用于取值
char[] split = equalationRight.replaceAll("[^A-Za-z]", "").toCharArray();
for (char s : split) {
String key = String.valueOf(s);
String val = DwuObject.valString(key, map);
//值为空则设置为0
if (StringUtils.isBlank(val)) {
val = "0";
}
//将值替换到公式中
equalationRight = equalationRight.replaceAll(key, val);
}
Object eval = jse.eval(equalationRight);
vaule = String.valueOf(eval);
//当被除数、除数都为0的情况和被除数为0的情况直接返回0
if (vaule.equals("NaN") || vaule.equals("Infinity")) {
return "0";
}
//最后一次计算
if (i == 0) {
if (symbol) {
vaule = vaule + "%";
}
} else {
map.put(equalationKey, vaule);
}
}
}
} catch (Exception t) {
}
return vaule;
}