java 对数学计算的使用性上还是比较麻烦的,遇到大量数据计算复杂的计算公式则会频发问题。接下来我们来统计一下在java中经常会遇到的计算问题
比如说我需要计算一下数据
100*2000/20*(20-10)
使用java原生BigDecimal来写计算会非常痛苦,所以封装了一套工具供大家使用
public void test(){
BigDecimal bigDecimal = new BigDecimal(100);
bigDecimal= bigDecimal.multiply(new BigDecimal(2000));
bigDecimal=bigDecimal.divide(new BigDecimal(20));
BigDecimal b2 = new BigDecimal(20);
BigDecimal b3 = new BigDecimal(10);
b2 = b2.subtract(b3);
bigDecimal = bigDecimal.multiply(b2);
System.out.println(bigDecimal.setScale(2).doubleValue());
}
使用MyMath 工具写法
public void myMathTest(){
MyMath.test("%s*%s/%s*(%s-%s)","100","2000","20","20","10");
}
不论是代码可读性,和代码量以及维护性功能都是大大提升的
MyMath 自动会处理科学计算法,异常数据等。使用的是js计算
String value1= MyMath.test("100*2000/20*(20-10)");
或者
String value= MyMath.test("%s*%s/%s*(%s-%s)","100","2000","20","20","10");
boolean b = MyMath.test2("10>=(5-1)");
或者
boolean b1 = MyMath.test2("%s>=(%s-%s)", "10", "5", "1");
得分计算如果都不满足条件则返回0分
String score = MyMath.getScore("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", "10", "20");
结果得10分
计算已,号做分割。从做往右依次计算。如果满足条件则返回:后面的得分,如果一个都未满足则返回0分
MyMath 核心代码
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MyMath {
String[] str = {"NaN", "Infinity"};
static ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
/**
* 判断
* (
*
* @param str 数学公式
* @return
*/
public static boolean test2(String str) {
str = str.replaceAll("null", "0");
try {
if (VerifyUtil.isEmpty(str)) return false;
str = str.replace("--", "+");
Object result = engine.eval(str);
if (result instanceof Boolean)
return (boolean) result;
} catch (ScriptException e) {
e.printStackTrace();
}
return false;
}
/**
* 判断计算
*
* @param str 数学占位符公式
* @param strs 替换数据
* @return
*/
public static boolean test2(String str, String... strs) {
str = String.format(str, strs);
return test2(str);
}
/**
* 累加
*
* @param baseNum
* @param num
* @return
*/
public static String append(String baseNum, String num) {
return MyMath.test(baseNum + "+" + getNumber(num));
}
/**
* 累加
*
* @param baseNum
* @param key
* @return
*/
public static String append(String baseNum, Map param, String key) {
if (VerifyUtil.isEmpty(param)) return "0";
return append(baseNum, getNumber(param.get(key)));
}
public static String getNumber(Object object) {
if (VerifyUtil.isEmpty(object)) return "0";
return object + "";
}
/**
* 判断
*
* @param str 数学公式
* @return
*/
public static boolean isInt(String str) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return false;
str = str.replace("--", "+");
Object result = null;
try {
result = engine.eval(str);
} catch (ScriptException e) {
e.printStackTrace();
return false;
}
if (result instanceof Boolean)
return (boolean) result;
return false;
}
/**
* 4位小数点
*
* @param str 数学公式
* @return
*/
public static String test(String str) {
return endMath(str, "###0.0000");
}
/**
* 计算得出结果
*
* @param str 占位符公式
* @param strs 替换值
* @return
*/
public static String test(String str, String... strs) {
str = String.format(str, strs);
return test(str);
}
/**
* 转换整数字符串,科学计算法也可以转换
*
* @param str
* @return
*/
public static String tesInt(String str) {
return endMath(str, "###0");
}
/**
* 8位小数点
*
* @param str
* @return
*/
public static String end8(String str) {
return endMath(str, "###0.00000000");
}
/**
* 保留小数点计算
*
* @param str 占位符公式
* @param toFixed 保留小数点数
* @param strs 替换值
* @return
*/
public static String test(String str, int toFixed, String... strs) {
str = String.format(str, strs);
return test(str, toFixed);
}
/**
* 抛出异常计算,用来定位做了什么处理
*
* @param str 占位符公式
* @param toFixed 保留小数位数
* @param strs 替换值
* @return
* @throws MathException 抛出异常,包含计算错误公式
*/
public static String testMathException(String str, int toFixed, String... strs) throws MathException {
str = String.format(str, strs);
return testException(str, toFixed);
}
/**
* 抛出异常计算,用来定位做了什么处理
*
* @param str 计算公式
* @param toFixed 保留小数位
* @return
* @throws MathException
*/
public static String testException(String str, int toFixed) throws MathException {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat("###0.0000");//格式化设置
result = decimalFormat.format(result);
if (isInteger(result + "")) {
BigDecimal bigDecimal = new BigDecimal(result + "");
result = bigDecimal.setScale(toFixed, BigDecimal.ROUND_HALF_UP).toPlainString();
}
} catch (ScriptException e) {
throw new MathException(str);
}
return isNumber(result + "");
}
/**
* 普通计算保留小数位
*
* @param str 计算公式
* @param toFixed 保留小数位
* @return
*/
public static String test(String str, int toFixed) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat("###0.0000");//格式化设置
result = decimalFormat.format(result);
if (isInteger(result + "")) {
BigDecimal bigDecimal = new BigDecimal(result + "");
result = bigDecimal.setScale(toFixed, BigDecimal.ROUND_HALF_UP).toPlainString();
}
} catch (ScriptException e) {
System.out.println("报错公式==== " + str);
e.printStackTrace();
}
return isNumber(result + "");
}
/**
* 是否是数字
*
* @param num
* @return
*/
public static String isNumber(String num) {
if (isInteger(num)) {
if (MyMath.test2(num + "==0")) return "0";
return num;
}
return "0";
}
/**
* 判断是否是计算数据类型
*
* @param obj
* @return
*/
public static boolean isInteger(Object obj) {
String str = obj + "";
return match("^(-)?[0-9]+(\\.[0-9]+)?$", str);
}
/**
* 是否有小数点
*
* @param str
* @return
*/
public static boolean isHavaFixed(String str) {
return str.contains(".");
}
/**
* @param regex 正则表达式字符串
* @param str 要匹配的字符串
* @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
*/
public static boolean match(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}
/**
* 数据计算指定格式
*
* @param str 计算公式
* @param form 指定格式
* @return
*/
public static String endMath(String str, String form) {
str = str.replaceAll("null", "0");
if (VerifyUtil.isEmpty(str)) return "0";
str = str.replace("--", "+");
Object result = 0;
try {
result = engine.eval(str);
DecimalFormat decimalFormat = new DecimalFormat(form);//防止科学计算
result = decimalFormat.format(result);
} catch (ScriptException e) {
System.out.println("报错公式==== " + str);
e.printStackTrace();
}
return isNumber(result + "");
}
/**
* @param input
* @return 判断是否是使用科学计数法的数字字符串
*/
public static boolean getScientific(String input) {
String regx = "^((-?\\d+.?\\d*)[Ee]{1}(-?\\d+))$";//科学计数法正则表达式
Pattern pattern = Pattern.compile(regx);
return pattern.matcher(input).matches();
}
/**
* 公式占比
* ("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", "10","20");
*
* @param math
* @return
*/
public static String getScore(String math, String... values) {
String score = "0";
String[] split = math.split(",");
for (String s : split) {
String itemMath = String.format(s, values);
String[] split1 = itemMath.split(":");
if (MyMath.test2(split1[0])) {
score = split1[1];
return score;
}
}
return score;
}
/**
* 结果计算,带权重
* ("Math.abs(%s-%s)<=10:10,Math.abs(%s-%s)<=15:5", 10, "10","20");
*
* @param math
* @return
*/
public static String getScore(String math, Object weight, String... values) {
String score = "0";
String[] split = math.split(",");
for (String s : split) {
String itemMath = String.format(s, values);
String[] split1 = itemMath.split(":");
if (MyMath.test2(split1[0])) {
score = split1[1];
score = MyMath.test(score + "*" + weight);
return score;
}
}
return score;
}
public static void main(String[] args) {
System.out.println(endMath("30021321321.332323", "#0.00"));
// System.out.println(test("(1+3)/10*10"));
// Double double1 = 123456789.123456789;
// Double double1 = 1.2345678912345679E8;
// DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");//格式化设置
// System.out.println(decimalFormat.format(double1));
// System.out.println(double1);
}
public static class MathException extends Exception {
String excMath;
public MathException() {
}
public MathException(String excMath) {
this.excMath = excMath;
}
public String getExcMath() {
return excMath;
}
public void setExcMath(String excMath) {
this.excMath = excMath;
}
}
}