纯java代码实现字符串运算符或公式计算,支持函数,不借助第三方依赖和工具
效果图
代码
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class StrFormulaUtil {public static void main(String[] args) {String str = "";str = "1*(5-3)/2";System.out.println(str+"的运算结果为:"+initResult(str));str = "20-IF(1>=2,5,6)";System.out.println(str+"的运算结果为:"+initResult(str));str = "20-SUM(1,2,3,4,5)";System.out.println(str+"的运算结果为:"+initResult(str));str = "20-AVG(2,4,8,2)";System.out.println(str+"的运算结果为:"+initResult(str));str = "20-MAX(1,2,3,4,5)";System.out.println(str+"的运算结果为:"+initResult(str));str = "20-MIN(1,2,3,4,5)";System.out.println(str+"的运算结果为:"+initResult(str));}public static String initResult(String info){return initBracket("("+info+")");}public static String initNum(String str){String symbol[] = {"+","-","*","/",">","<","=","!=",">=","<="};int add = str.indexOf("+");int subtract = str.indexOf("-");if (subtract!=-1){String num="";if (subtract-1>=0){num = str.substring(subtract-1, subtract);try {Integer.parseInt(num);} catch(NumberFormatException e) {subtract=-1;}}else {subtract=-1;}}int multiply = str.indexOf("*");int divide = str.indexOf("/");int dy = str.indexOf(">");int xy = str.indexOf("<");int dd = str.indexOf("=");int bdd = str.indexOf("!=");int dyd = str.indexOf(">=");int xyd = str.indexOf("<=");int i=0;int j=0;if (multiply==-1&÷==-1&&add==-1&&subtract==-1&&dy==-1&&xy==-1&&dd==-1&&dyd==-1&&xyd==-1){return str;}if (multiply!=-1||divide!=-1){j=1;i=(multiply==-1)?divide:((divide==-1)?multiply:(multiply<divide?multiply:divide));}else if (add!=-1||subtract!=-1){j=1;i=(add==-1)?subtract:((subtract==-1)?add:(add<subtract?add:subtract));}else if (bdd!=-1||dyd!=-1||xyd!=-1){j=2;Integer index[] = {bdd,dyd,xyd};List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());i= Collections.min(indexList);}else if (dy!=-1||xy!=-1||dd!=-1){j=1;Integer index[] = {dy,xy,dd};List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());i=Collections.min(indexList);}String strs = "";if (Arrays.asList(symbol).contains(str.substring(i,i+j))){String regex = "[\\+\\-\\*/><=(!=)(>=)(<=)]";String left = str.substring(0, i);String right = str.substring(i+j, str.length());String[] lefts = left.split(regex);String[] rights = right.split(regex);if ("-".equals(right.charAt(0)+"")){rights=right.substring(1).split(regex);rights[0] = "-"+rights[0];}String leftStr = left.substring(0,left.length()-lefts[lefts.length - 1].length());String rightStr = right.substring(rights[0].length(),right.length());if ("*".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+leftNum.multiply(rightNum)+rightStr;}else if ("/".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+leftNum.divide(rightNum,4,BigDecimal.ROUND_HALF_UP)+rightStr;}else if ("+".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+leftNum.add(rightNum)+rightStr;}else if ("-".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+leftNum.subtract(rightNum)+rightStr;}else if ("!=".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)!=0)+rightStr;}else if (">=".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)>=0)+rightStr;}else if ("<=".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)<=0)+rightStr;}else if (">".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)>0)+rightStr;}else if ("<".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)<0)+rightStr;}else if ("=".equals(str.substring(i,i+j))){BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);BigDecimal rightNum = new BigDecimal(rights[0]);strs = leftStr+(leftNum.compareTo(rightNum)==0)+rightStr;}else {strs = left+str.substring(i,i+j)+right;}}boolean flag = false;for (String item : Arrays.asList(symbol)) {if (strs.contains(item)){flag = true;}}if (flag){strs = initNum(strs);}return strs;}public static List<Integer> getStrToIndexOf(String info,String select){List<Integer> countList = new ArrayList<>();if (info==null){return countList;}int start = 0;int index = select.length();while (true) {if (info.indexOf(select, start) != -1) {start = info.indexOf(select, start);countList.add(start);start += index; } else {break;}}return countList;}public static String initBracket(String body){List<Integer> startList = getStrToIndexOf(body, "(");List<Integer> endList = getStrToIndexOf(body, ")");Integer end = endList.get(0);Integer start = Collections.max(startList.stream().filter(s -> s < end).collect(Collectors.toList()));String left = body.substring(0,start);String right = body.substring(end+1,body.length());String middle = body.substring(start+1,end);if (left.length()>=2&&"IF".equals(left.substring(left.length()-2,left.length()))){middle = initIf(middle);left = left.substring(0,left.length()-2);}else if (left.length()>=3&&"SUM".equals(left.substring(left.length()-3,left.length()))){middle = initSUM(middle);left = left.substring(0,left.length()-3);}else if (left.length()>=3&&"AVG".equals(left.substring(left.length()-3,left.length()))){middle = initAVG(middle);left = left.substring(0,left.length()-3);}else if (left.length()>=3&&"ABS".equals(left.substring(left.length()-3,left.length()))){middle = initABS(middle);left = left.substring(0,left.length()-3);}else if (left.length()>=3&&"MAX".equals(left.substring(left.length()-3,left.length()))){middle = initMAX(middle);left = left.substring(0,left.length()-3);}else if (left.length()>=3&&"MIN".equals(left.substring(left.length()-3,left.length()))){middle = initMIN(middle);left = left.substring(0,left.length()-3);}else {middle = initNum(middle);}String content = left+middle+right;if (content.indexOf("(")!=-1||content.indexOf(")")!=-1){content = initBracket(content);}return content;}public static String initIf(String str){String[] split = str.split(",");String condition = initNum(split[0]);String trueValue = initNum(split[1]);String falseValue = initNum(split[2]);if ("true".equals(condition)){return trueValue;}if ("false".equals(condition)){return falseValue;}if (Integer.valueOf(condition)>0){return trueValue;}else {return falseValue;}}public static String initSUM(String str){String[] split = str.split(",");BigDecimal sumAmount = new BigDecimal(0);for (String s : split) {sumAmount=sumAmount.add(new BigDecimal(initNum(s)));}return sumAmount.toString();}public static String initAVG(String str){String[] split = str.split(",");BigDecimal sumAmount = new BigDecimal(0);for (String s : split) {sumAmount=sumAmount.add(new BigDecimal(initNum(s)));}return sumAmount.divide(new BigDecimal(split.length),4,BigDecimal.ROUND_HALF_UP).toString();}public static String initABS(String str){double abs = Math.abs(Double.valueOf(initNum(str)));return abs+"";}public static String initMAX(String str){String[] split = str.split(",");BigDecimal maxAmount = new BigDecimal(0);for (String s : split) {if (new BigDecimal(initNum(s)).compareTo(maxAmount)>0){maxAmount = new BigDecimal(initNum(s));}}return maxAmount.toString();}public static String initMIN(String str){String[] split = str.split(",");BigDecimal minAmount = new BigDecimal(initNum(split[0]));for (String s : split) {if (new BigDecimal(initNum(s)).compareTo(minAmount)<0){minAmount = new BigDecimal(initNum(s));}}return minAmount.toString();}
}