纯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();
}
}