首页 > 编程语言 >如何在Java里进行数学公式计算?

如何在Java里进行数学公式计算?

时间:2022-12-26 17:35:05浏览次数:43  
标签:数学公式 Java String script static 计算 import java net

我们在平常开发的时候,难免会遇到涉及数学公式计算的业务场景。

例如给一个公式,(1+P)*T=?,其中P和T是两个变量,当T=11、P=110时,这个公式计算的结果是多少呢?

下面给出具体实现的工具类,其实现逻辑是在Java里运行JavaScript代码。

直接运行main方法就可以得到结果了,想要换一个公式或者公式里的变量或值,就直接改下红色字体的代码即可。

import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import javax.script.*;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 使用java进行数学公式计算
 * @Author: 夏威夷8080
 * @Date: 2011/9/27 14:59
 */
@Slf4j
public class ComputeUtil {

    /**
     * js 关键词 黑名单
     */
    private static final Set<String> blacklist = Sets.newHashSet(
            // Java 全限定类名
            "java.io.File", "java.io.RandomAccessFile", "java.io.FileInputStream", "java.io.FileOutputStream",
            "java.lang.Class", "java.lang.ClassLoader", "java.lang.Runtime", "java.lang.System", "System.getProperty",
            "java.lang.Thread", "java.lang.ThreadGroup", "java.lang.reflect.AccessibleObject", "java.net.InetAddress",
            "java.net.DatagramSocket", "java.net.DatagramSocket", "java.net.Socket", "java.net.ServerSocket",
            "java.net.MulticastSocket", "java.net.MulticastSocket", "java.net.URL", "java.net.HttpURLConnection",
            "java.security.AccessControlContext", "java.lang.ProcessBuilder",
            // JavaScript 方法
            "eval","new function");

    static Compilable compilable;
    static Bindings bindings;
    static {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
        compilable = (Compilable) engine;
        // Local级别的Binding
        bindings = engine.createBindings();
    }

    /**
     * 设置变量值
     * @param key 变量key
     * @param value 变量value
     */
    public static void putBindings(String key, String value){
        bindings.put(key, value);
    }

    /**
     * 清除变量值
     */
    public static void clearBindings(){
        bindings.clear();
    }

    /**
     * 计算公式
     * @param script  示例:(1+0.1 * (F/10) * T)*P
     */
    public static Double eval(String script) throws ScriptException {
        checkInsecureKeyword(script);
        CompiledScript JSFunction = compilable.compile(script);
        return Double.valueOf(String.valueOf(JSFunction.eval(bindings)));
    }

    private static void checkInsecureKeyword(String script) throws ScriptException {
        // 去除注释
        String removeComment = RegExUtils.replacePattern(script, "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)", "");
        // 多个空格替换为一个
        String finalCode = RegExUtils.replacePattern(removeComment, "\\s+", " ");
        Set<String> insecure = blacklist.stream().filter(s -> StringUtils.containsIgnoreCase(finalCode, s))
                .collect(Collectors.toSet());
        if (!CollectionUtils.isEmpty(insecure)) {
            throw new ScriptException("解析到js脚本[" + script + "]是不安全的");
        }
    }

    public static void main(String[] args) {
        bindings.put("T", 11);
        bindings.put("P", 110);
        try {
            System.out.println(eval("(1+P)*T"));
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
}

以上就是如何在Java里进行数学公式计算的介绍,希望对你有帮助。

标签:数学公式,Java,String,script,static,计算,import,java,net
From: https://www.cnblogs.com/shamo89/p/17006268.html

相关文章

  • oss连接出现java.lang.IllegalArgumentException: Oss endpoint can't be empty.问题
    场景:在bootstrap.properties中编写nacos的配置,读取在nacos中定义的数据集连接ossspringboot版本为2.6.8结果就出现了以上错误原因:通过查找资料后发现,在springboot2.4......
  • Java同步器之ReentrantLock源码分析(一)
    一、概述ReentrantLock是Java并发包中提供的一个可重入的互斥锁。ReentrantLock和synchronized在基本用法,行为语义上都是类似的,同样都具有可重入性。只不过相比原生的Syn......
  • JAVA基于权重的抽奖
     如有4个元素A、B、C、D,权重分别为1、2、3、4,随机结果中A:B:C:D的比例要为1:2:3:4。总体思路:累加每个元素的权重A(1)-B(3)-C(6)-D(10),则4个元素的的权重管辖区间分别为[0,1......
  • Java同步器之AQS源码分析
    一、简介AbstractQueuedSynchronizer(简称AQS),抽象的队列式的同步器,是Java并发包实现的基类。AQS用来构建锁和同步器的框架,使用AQS能简单且高效地构造出大量的应用广泛......
  • Java类MemoryUsage查看虚拟机的使用情况
     Arthas是阿里巴巴开源的一款监控java进程的工具,可以有效监控CPU、内存使用情况,更厉害的是可以帮助开发人员深入排查java代码的问题,比如java进程占用cpu过高是哪一个线程......
  • https Java SSL Exception protocol_version
      在java代码中,使用HttpClient爬取https页面时,遇到了这个bug:javax.net.ssl.SSLException:Receivedfatalalert:protocol_version     先奉上初始的代码:1/**2......
  • javascript使用正则表达式替换或者捕获子字符串
    letstring='mutiFile[{"name":"新建文件夹(2).zip","ext":".zip","size":1675876,"path":"/static/upload/2022December/ba145698fcc99fd414f0f4ec6ea418e5.zip"}]';......
  • java获取stream流
    java获取stream流可以通过以下四种方式获取1通过list集合获取,list.stream()List<String>list=newArrayList<>();list.add("北京");list.add("上海");list.add("......
  • 阿里巴巴2020届秋招最后一班车 企业智能事业部 企业大脑技术部 2020届秋招 Java 开发
    阿里巴巴企业智能事业部企业大脑技术部2020届秋招-JAVA工程师阿里巴巴企业智能事业部,2020年秋季校招最后一班车啦:JAVA开发工程师虚位以待,机会难得,占坑抓紧。入职就发师兄,一......
  • idea java开发给方法上加注释
    打开IDEA开发工具,file->setting->Editor->LiveTemplates点加号选择templategroup随便起一个名字点击加号,选择LiveTemplate依次填上红框中的......