MVEL实现java直接根据公式计算结果
2017-09-06 00:00
477 查看
摘要: MVEL实现java直接根据公式计算结果
工具类
异常类
字符串工具类
测试类简单粗暴String Double Integer Bigdecimal 都能支持
工具类
import java.math.BigDecimal; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; import org.mvel2.CompileException; import org.mvel2.MVEL; import org.mvel2.PropertyAccessException; /** * 计算工具 * * @author valsong * @date Jul 24, 2017 * */ public class CalculateUtils { /** * 根据传入的公式和参数进行计算 * * @param formula * @param variables * @return */ public static <T> BigDecimal calculate(String formula, Map<String, T> variables) { if (SimpleStringUtils.isBlank(formula)) { throw new CalculateException("MVEL formula can't be null! formula : " + formula); // 公式不能为空 } if (variables == null || variables.size() == 0) { throw new CalculateException("MVEL variables can't be null! variables : " + String.valueOf(variables)); // 参数不能为空 } try { // 将公式中的变量全部转化为BigDecimal类型 variables.entrySet().stream().filter(e -> e != null && e.getKey() != null && e.getValue() != null) .map(CalculateUtils::convert).collect(Collectors.toMap(Entry::getKey, Entry::getValue)); } catch (NumberFormatException e) { throw new CalculateException( "MVEL can't convert to BigDecimal, please check the variables : " + String.valueOf(variables) + "!", e); } catch (Exception e) { throw e; } BigDecimal result = null; try { result = (BigDecimal) MVEL.eval(formula, variables); } catch (PropertyAccessException pae) { throw new CalculateException( "MVEL please check the formula :" + formula + " & variables : " + String.valueOf(variables) + "!", pae); } catch (CompileException ce) { throw new CalculateException("MVEL calculate error! ", ce); } catch (Exception e) { throw e; } return result; } /** * 将参数转化为Bigdecimal类型 * * @param entry * @return */ @SuppressWarnings("unchecked") public static <T> Entry<String, T> convert(Entry<String, T> entry) { if (entry != null) { BigDecimal value = null; if (entry.getValue() instanceof BigDecimal) { value = (BigDecimal) entry.getValue(); } else { value = NumberUtils.getNum(NumberUtils.getNum(entry.getValue())); } entry.setValue((T) value); } return entry; } }
异常类
/** * 计算异常 * * @author Val Song * @date Jul 28, 2017 * */ public class CalculateException extends RuntimeException { private static final long serialVersionUID = 5162710183389028792L; /** * Constructs a {@code CalculateException} with no detail message. */ public CalculateException() { super(); } /** * Constructs a {@code CalculateException} with the specified detail * message. * * @param message * the detail message. */ public CalculateException(String message) { super(message); } /** * Constructs a {@code CalculateException} with the specified detail * message & cause * * @param message * @param cause */ public CalculateException(String message, Throwable cause) { super(message, cause); } }
字符串工具类
/** * 字符串工具 * * @author valsong * */ public class SimpleStringUtils { /** * 判断字符串不为空 * * @param str * @return */ public static boolean isNotBlank(String str) { return !isBlank(str); } /** * 判断字符串为空 * * @param str * @return */ public static boolean isBlank(String str) { if (str == null || "".equals(str.trim())) { return true; } return false; } /** * 去首尾空格 * * @param s * @return */ public static <T> String trim(T s) { if (s instanceof String) { return s == null ? null : ((String) s).trim(); } else { return s == null ? null : String.valueOf(s).trim(); } } /** * 下划线命名转驼峰式 * * @param str * @return */ public static String toCamel(String str) { if (SimpleStringUtils.isBlank(str)) { return str; } StringBuffer buffer = new StringBuffer(); str = str.toLowerCase().trim(); char[] charArray = str.toCharArray(); if (charArray != null) { for (int i = 0; i < charArray.length; i++) { if ('_' == charArray[i]) { i = i + 1; buffer.append(Character.toUpperCase(charArray[i])); } else { buffer.append(charArray[i]); } } } return buffer.toString(); } /** * 驼峰转下划线 * * @param str * @return */ public static String toUnderline(String str) { if (SimpleStringUtils.isBlank(str)) { return str; } StringBuffer buffer = new StringBuffer(); str = str.trim(); char[] charArray = str.toCharArray(); if (charArray != null) { for (int i = 0; i < charArray.length; i++) { if (Character.isUpperCase(charArray[i])) { buffer.append("_"); buffer.append(Character.toLowerCase(charArray[i])); } else { buffer.append(charArray[i]); } } } return buffer.toString(); } }
测试类简单粗暴String Double Integer Bigdecimal 都能支持
public class CalculateUtilsTest { /** * 20 * 100 - ( 30 -20 ) + 20 ^ 3 + 20/2 */ @Test public void calculateTest4() { String formula = "A * B - (C -D) + E.pow(F) + G / H"; Map<String, Object> variables = new HashMap<>(); variables.put("A", "20"); variables.put("B", 100L); variables.put("C", 30.0D); variables.put("D", 20); variables.put("E", new BigDecimal("20")); variables.put("F", "3"); variables.put("G", "20"); variables.put("H", "2"); BigDecimal result = CalculateUtils.calculate(formula, variables); Assert.assertTrue(new BigDecimal("10000.0").compareTo(result) == 0); } }
相关文章推荐
- MVEL实现java直接根据公式计算结果
- 根据两点经纬度计算精确距离,结果和百度地图测距一样——java实现
- 黑马程序员 Java中根据YYYY-MM-DD格式的日期计算为星期几的两种实现方式
- 【项目实战】——Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)
- Java 如何直接获得字符串形式计算的结果
- 二叉树定义及相关术语、节点数计算公式、代码实现(遍历,Java版)
- 重点:java后端直接连接数据库实现查询获取结果 jdbc
- c#根据公式进行自动计算的实现
- Java实现中缀表达式转后缀表达式并计算结果
- 根据公式计算y的值。其中∑表示求各项的和,∏表示求各项的积。定义一个类F,实现上述功能。具体要求如下:
- Windows平台下GCC编程之根据以下公式计算s,计算结果作为函数值返回;n通过形参传入。 s=1+1/3+1/5+···+1/(2n-1)
- 根据经纬度计算两地距离java实现
- c#根据公式进行自动计算的实现
- 根据公式计算结果
- 使用Java语言,使用System.in输入以下各个变量的值,并按照公式计算得出结果。 公式为: 4/3*(r+34)-9*(a+b*c)+(3+d*(2+a))/(a+b*d)
- excel导出时 如何根据java后台返回的结果 动态实现excel复选框的勾选
- c#根据公式进行自动计算的实现
- java阶乘计算获得结果末尾0的个数代码实现
- Java程序实现根据经纬度计算GPS点的距离
- JAVA实现的可以带参数的公式表达式计算