一篇掌握Jep灵活应用,数学公式自定义

基于 Jep 的 Java 调用 Python 技术 在混合编程场景中,Java 和 Python 各有优势,有时需要在 Java 程序中调用 Python 代码。Jep 是一个用于在 Java 虚拟机中嵌入 Python 解释器的工具,支持 Java 和 Python 之间的相互调用。本文将介绍如何使用 Jep 实现 Java 程序调用 Python 代码,并传递参数和接收返回值。高效的数据传递:Jep 允许 Java 和 Python 在同一个进程中共享内存,数据传递无需序列化和反序列化,提高了效率。性能优越。 阅读详情

        自定义数学公式:jep灵活运用。

        由于最近事情比较繁忙,所以就没有静下心或者有时间去将所学的东西整理分享。今天忙里偷闲,分享一篇关于jep的灵活使用。

        浏览了很多关于jep的文章,感觉都是在原本jep的基础上去应用,计算一些数据。比较局限,那么我在根据自己的业务需求的时候,看了下jep的源码,并且添加了部分代码去更加灵活的应用。

业务需求

为什么想到去用jep呢,是因为我在项目过程中遇到了一个,希望可以自己自定义统计量公式的需求,例如平均值,方差,还有根据他们的值进行一些权重分配,混合运算的要求,那么需要根据存储在数据库中的字符串表达式,来在后端进行动态的识别,并且读取数据,根据公式字符串,返回对应统计量的结果。

我们希望传入动态的数据,根据不同的公式,计算出值。

jep重要源码及使用

最开始忘记给出jep依赖包了,这次更新补充一下

<!--        jep依赖-->
        <dependency>
            <groupId>org.scijava</groupId>
            <artifactId>jep</artifactId>
            <version>2.4.2</version>
        </dependency>

首先我们先简介一下jep。

JEP是Java expression parser的简称,即java表达式分析器,Jep是一个用来转换和计算数学表达式的java库。通过这个程序包,用户可以以字符串的形式输入一个、任意的公式,然后快速地计算出结果。Jep支持用户自定义变量、常量和函数。包括许多常用的数学函数和常量。

这些都是封装好的函数。

	public void addStandardFunctions() {
		//add functions to Function Table
		funTab.put("sin", new Sine());
		funTab.put("cos", new Cosine());
		funTab.put("tan", new Tangent());
		funTab.put("asin", new ArcSine());
		funTab.put("acos", new ArcCosine());
		funTab.put("atan", new ArcTangent());
		funTab.put("atan2", new ArcTangent2());

		funTab.put("sinh", new SineH());
		funTab.put("cosh", new CosineH());
		funTab.put("tanh", new TanH());
		funTab.put("asinh", new ArcSineH());
		funTab.put("acosh", new ArcCosineH());
		funTab.put("atanh", new ArcTanH());

		funTab.put("log", new Logarithm());
		funTab.put("ln", new NaturalLogarithm());
		funTab.put("exp", new Exp());
		funTab.put("pow", new Power());

		funTab.put("sqrt",new SquareRoot());
		funTab.put("abs", new Abs());
		funTab.put("mod", new Modulus());
		funTab.put("sum", new Sum());

		funTab.put("rand", new org.nfunk.jep.function.Random());
		
		// rjm additions
		funTab.put("if", new If());
		funTab.put("str", new Str());
		
		// rjm 13/2/05
		funTab.put("binom", new Binomial());
		
		// rjm 26/1/07
		funTab.put("round",new Round());
		funTab.put("floor",new Floor());
		funTab.put("ceil",new Ceil());
	}

简单的来说,就是可以用算术运算符代替之前的java的公式,显示和逻辑编写更加清晰简单。

我们继续深层的读取源码,会发现它继承了一个类:

PostfixMathCommand:

public class PostfixMathCommand implements PostfixMathCommandI {
    protected int numberOfParameters = 0;
    protected int curNumberOfParameters = 0;

    public PostfixMathCommand() {
    }

    protected void checkStack(Stack inStack) throws ParseException {
        if (null == inStack) {
            throw new ParseException("Stack argument null");
        }
    }

    public int getNumberOfParameters() {
        return this.numberOfParameters;
    }

    public void setCurNumberOfParameters(int n) {
        this.curNumberOfParameters = n;
    }

    public boolean checkNumberOfParameters(int n) {
        if (this.numberOfParameters == -1) {
            return true;
        } else {
            return this.numberOfParameters == n;
        }
    }

    public void run(Stack s) throws ParseException {
        throw new ParseException("run() method of PostfixMathCommand called");
    }
}

那么这里面比较有用的两个参数:

 protected int numberOfParameters = 0;
 protected int curNumberOfParameters = 0;

一个表示可变参数,一个表示参数个数。

为什么重要呢,因为这里面的函数计算,会是栈的计算,也就是会把传入参数弹出之后,将计算结果存入栈里返回,如果像定义一个公式sum(data)/count(data),那么count运算时候,弹栈的时候,就不能把sum存入的结果也弹出了,为什么会这么说,因为我最开始运用弹出数据控制的时候,就是用的inStack.isEmpty()方法来控制循环的,所以最后会返回NaN的结果,我们需要根据curNumberOfParameters来进行循环。

简单代码示例

看了上面的说明,如果是初次接触可能会很懵,没关系,我们看一下简单实例来理解。

@Test
    public void getValueNet(){
        JEP jep = new JEP();
        // 添加常用函数
        jep.addStandardFunctions();
        // 添加常用常量
        jep.addStandardConstants();

        String exp = "M12*3.14/4"; //给变量赋值

         jep.addVariable("M12", 6.0);

        try { //执行
            jep.parseExpression(exp);
            double result = jep.getValue();
            System.out.println("计算结果: " + result);
        } catch (Throwable e) {
            System.out.println("An error occured: " + e.getMessage());
        }
    }

这便是最简单的jep代码示例:

下面我通过图片来解释:

不足的地方

如果说,只是计算一两个数,给定的公式,给定的数据集,而且必须很小,才能这样计算,因为我们看源码发现,这个jep原本add变量的时候,竟然是一个一个加的。

这里的symTab就是它存储变量,也就是后面用来公式识别的一个成员变量。

说白了,就是太笨拙了,而我们后端需要的数据,是变化的,因此,我们需要更改源码,并且编写工具类,来提升它。

修改源码

我规定传入的时候是:

count(A1,A2,A3,....)等等这样的数据

JepPlus

public class JepPlus extends JEP {

    public JepPlus(){
        super();
    }
    public Double addVariable(String name, double value) {
        Double object = new Double(value);
        //这个就是读取对象放进去,给对应的字符串对应值
        this.symTab.makeVarIfNeeded(name, object);
        return object;
    }

    public void addArrayVariable(List<String> value){
       //现在接收到一个数组,data。data里有三个数据
        // 现在我们遍历数组,给数组的每个对象按顺序起一名字并把对应的值放入进去
       for(int i=0;i<value.size();i++){
           this.symTab.makeVarIfNeeded("A"+(i+1),Double.parseDouble(value.get(i)));
       }
    }
}

快排工具类:

package com.neu.statistics.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class QuickSortUtil {

    public static void main(String[] args) {
        List<Double> arr= new ArrayList<>();

        System.out.println("原始数组:"+ Arrays.toString(arr.toArray()));
        //获取数组arr的长度

        List<Double> newList = quickSort(arr, 0, arr.size() - 1);
        System.out.println("排序后的数组:"+ Arrays.toString(newList.toArray()));

    }
    public static List<Double> quickSort(List<Double> arr, int left, int right) {

        //递归结束条件left < right
        if (left < right) {
            // 通过分区函数得到基准元素的索引
            int pivotIndex = partition(arr, left, right);
            //递归对基准元素左边的子数组进行快速排序
            quickSort(arr, left, pivotIndex - 1);
            //递归对基准元素右边的子数组进行快速排序
            quickSort(arr, pivotIndex + 1, right);
        }

        return arr;

    }

    public static int partition(List<Double> arr, int left, int right) {
        // 选择最后一个元素作为基准元素
        double pivot = arr.get(right);
        int i = left;
        //int[] arr = new int[]{5,7,3,3,6,4};

        //循环数组,如果满足条件,则将满足条件的元素交换到arr[i],同时i++,循环完成之后i之前的元素则全部为小于基准元素的元素
        for (int j = left; j < right; j++) {
            if (arr.get(j) < pivot) {
                if (j != i) {
                    swap(arr, i, j);
                }
                i++;//数交换之后,需要左指针i右移
            }
        }

        // 交换 arr[i] 和基准元素
        swap(arr, i, right);
        //返回基准元素的下标
        return i;
    }

    public static void swap(List<Double> arr, int left, int right) {
        double temp = arr.get(left);
        //交换list中的两个元素
        arr.set(left, arr.get(right));
        arr.set(right, temp);
    }


}

字符串转换工具类

我这里定义我的数据库存储数据,数据集合统一用data来表示。以后也可以根据业务不同需求来进行扩展。

由于我们数据库存储的是sum(data)/count(data)

那么data是我们传入的一组字符串数据,我们需要在识别到data之后,把他变成sum(A1,A2,A3)/count(A1,A2,A3),这样jep就可以将变量A1,A2,A3存入他的成员变量里面

package com.neu.statistics.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DynamicStringConversion {

    public static void main(String[] args) {
        // 原始表达式
        String formula = "sum(data)/count(data)";

        // 模拟从数据库或其他源获取数据
        List<String> dataList = new ArrayList<>();
        dataList.add("1");
        dataList.add("2");
        dataList.add("3");

        // 动态转换表达式
        String dynamicFormula = convertFormula(formula, dataList);

        // 输出转换后的表达式
        System.out.println("初始字符串: " + formula);
        System.out.println("转换后的字符串: " + dynamicFormula);
    }

    // 动态替换表达式中的 data
    public static String convertFormula(String formula, List<String> dataList) {
        // 匹配 data 字符串的正则表达式
        String regex = "\\bdata\\b";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(formula);

        // 动态替换每个匹配的 data
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            // 将匹配到的 data 替换为 a1, a2, a3 格式
            matcher.appendReplacement(result, buildReplacement(dataList));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    // 根据 dataList 构建替换字符串,使用 a1, a2, ... 的变量名
    public static String buildReplacement(List<String> dataList) {
        // 构建 a1, a2, a3 格式
        StringBuilder replacement = new StringBuilder();
        for (int i = 0; i < dataList.size(); i++) {
            replacement.append("A").append(i + 1);
            if (i < dataList.size() - 1) {
                replacement.append(", ");
            }
        }
        return replacement.toString();
    }
}

自定义公式

目前我写了平均值,最大值,最小值方差等公式,以后我会根据业务需求继续拓展,目前给出这些。

package com.neu.statistics.utils;

import org.nfunk.jep.ParseException;
import org.nfunk.jep.function.PostfixMathCommand;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

public class FormulaCalculator {


    public String calculateFormula(List<String> valueList, String formula) throws ParseException {
        String exp = DynamicStringConversion.convertFormula(formula, valueList);
        JepPlus jep = new JepPlus();
        jep.addStandardFunctions(); // 添加标准函数(可选)
        jep.addStandardConstants(); // 添加标准常量(可选)
        // 注册自定义的 sum 和 count 函数
        jep.addFunction("sum", new SumFunction());
        jep.addFunction("count", new CountFunction());
        jep.addFunction("min",new MinFunction());
        jep.addFunction("max",new MaxFunction());
        jep.addFunction("median",new MedianFunction());
        jep.addFunction("variance",new VarianceFunction());
        jep.addArrayVariable(valueList);
        jep.parseExpression(exp);
        // 输出结果
        return String.valueOf(jep.getValue());
    }

}




//求和
class SumFunction extends PostfixMathCommand {


    public SumFunction(){
        numberOfParameters = -1; //可变参数
    }

    @Override
    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for(int i=0;i<this.curNumberOfParameters;i++){
            params.add(inStack.pop());
        }
        inStack.push(this.sum(params));
    }

    public Object sum(List<Object> params) throws ParseException {
        double sum=0.0;
        for (Object param : params) {
            if (param instanceof Number) {
                sum += ((Number)param).doubleValue();
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        return sum;
    }

}

//求总数
class CountFunction extends PostfixMathCommand{

    public CountFunction(){
        numberOfParameters = -1; //可变参数
    }
    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for(int i=0;i<this.curNumberOfParameters;i++){
            params.add(inStack.pop());
        }
//        while(!inStack.isEmpty()){
//            params.add(inStack.pop());
//        }
        inStack.push(this.count(params));
    }
    public Object count(List<Object> params) throws ParseException {
        double count=0.0;
        for (Object param : params) {
            if (param instanceof Number) {
                count += 1;
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        return count;
    }

}

//求最小值
class MinFunction extends PostfixMathCommand {

    public MinFunction() {
        numberOfParameters = -1; //可变参数
    }

    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < this.curNumberOfParameters; i++) {
            params.add(inStack.pop());
        }
        inStack.push(this.min(params));

    }
    public Object min(List<Object> params) throws ParseException{
        //快速排序,返回最小值,也就是数组的第一个元素
        //将object转换为double
        List<Double> list = new ArrayList<>();
        for (Object param : params) {
            if (param instanceof Number) {
                list.add(((Number) param).doubleValue());
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        List<Double> newList=QuickSortUtil.quickSort(list,0,list.size()-1);
        Object result=newList.get(0);
        return result;
    }

}

//求最大值
class MaxFunction extends PostfixMathCommand {

    public MaxFunction() {
        numberOfParameters = -1; //可变参数
    }

    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < this.curNumberOfParameters; i++) {
            params.add(inStack.pop());
        }

        inStack.push(this.max(params));
    }
    public Object max(List<Object> params) throws ParseException{
        //快速排序,返回最小值,也就是数组的第一个元素
        //将object转换为double
        List<Double> list = new ArrayList<>();
        for (Object param : params) {
            if (param instanceof Number) {
                list.add(((Number) param).doubleValue());
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        List<Double> newList=QuickSortUtil.quickSort(list,0,list.size()-1);
        Object result=newList.get(list.size()-1);
        return result;
    }

}

//中位数
class MedianFunction extends PostfixMathCommand {

    public MedianFunction() {
        numberOfParameters = -1; //可变参数
    }

    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < this.curNumberOfParameters; i++) {
            params.add(inStack.pop());
        }
        inStack.push(this.median(params));
    }
    public Object median(List<Object> params) throws ParseException{
        //快速排序,返回最小值,也就是数组的第一个元素
        //将object转换为double
        List<Double> list = new ArrayList<>();
        for (Object param : params) {
            if (param instanceof Number) {
                list.add(((Number) param).doubleValue());
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        List<Double> newList=QuickSortUtil.quickSort(list,0,list.size()-1);
        int length=newList.size();
        if(newList.size()%2==0){
            Object result=(newList.get(length/2)+newList.get(length/2-1))/2;
            return result;
        }
        else{
            Object result=newList.get(length/2);
            return result;
        }
    }

}

//方差
class VarianceFunction extends PostfixMathCommand {

    public VarianceFunction() {
        numberOfParameters = -1; //可变参数
    }

    public void run(Stack inStack) throws ParseException {
        //检查栈
        this.checkStack(inStack);
        List<Object> params = new ArrayList<>();
        for (int i = 0; i < this.curNumberOfParameters; i++) {
            params.add(inStack.pop());
        }
        inStack.push(this.variance(params));
    }
    public Object variance(List<Object> params) throws ParseException{
        SumFunction sf=new SumFunction();
        double sum=(double)sf.sum(params);
        CountFunction cf=new CountFunction();
        double count=(double)cf.count(params);
        double average=sum/count;
        //快速排序,返回最小值,也就是数组的第一个元素
        //将object转换为double
        List<Double> list = new ArrayList<>();
        for (Object param : params) {
            if (param instanceof Number) {
                list.add(((Number) param).doubleValue());
            } else {
                throw new ParseException("Invalid parameter type");
            }
        }
        List<Double> newList=QuickSortUtil.quickSort(list,0,list.size()-1);
        double sumOfSquaredDifferences = 0.0;
        for(double value:newList){
            double difference=value-average;
            sumOfSquaredDifferences+=difference*difference;
        }
        Object result=sumOfSquaredDifferences/count;
        return result;
    }

}

应用示例:

    @Test
    public void test1() throws ParseException {
        List<String> list=new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        String formula = "variance(data)";
        FormulaCalculator formulaCalculator=new FormulaCalculator();
        String result = formulaCalculator.calculateFormula(list,formula);
        System.out.println(result);
    }

java通过jep(Java Embedded Python)实现高效重复调用python脚本 跨语言调用java调用python 阅读详情

相关推荐

jepglib库源码

jepglib库是一个jpeg压缩库,本压缩包提供了该库的源代码。

jep(java表达式分析器)简介

1 简介 jep是Java expression parser的简称,即java 表达式转换器。 能够将字符串形式的公式,配置对应的参数得到计算结果。 属于比较老的项目,最新版本Jep 3.5,官网最后一次维护为2018年7月。 官网: http://www.singularsys.com/jep/ 中文参考网站: https://www.ibm.com/developerworks/cn/java/j-lo-jep/ 官网介绍如下: Jep Java仅用几行代码解析和计算数学表达式。这个包允许用户以字符

weixin_55891090的博客 1万+

解决相同型号USB设备在Windows系统中重复枚举问题

本文详细解析了Windows系统中相同型号USB设备重复枚举问题的成因及解决方案。通过修改注册表、使用PsTools工具清除设备记录以及编程实现自动化处理等方法,有效解决设备识别混乱问题,特别适用于自动化测试和工业设备管理场景。

weixin_42561040的博客 563

探索 JEP:一个高效的 Java 调用 Python 库的工具

如果你在寻找一种简单高效的方式来调用 Python 库以扩展你的 Java 程序,那么 JEP(Java-Embedded Python)可能是一个不错的选择。 ## 什么是 JEP? JEP 是一个开源项目,它提供了一种将 Python 代码嵌入 Java 应用程序中的方法。通过 JEP,你可以直接从 Java 代码中执行 Python 语句或调用 Python 函数,从而利用 Python...

gitblog_00023的博客 1611

CameraLink接口详解:从引脚定义到信号传输

本文详细解析了CameraLink接口的物理连接与信号传输机制。从MDR26连接器的引脚定义与镜像关系入手,深入讲解了BASE与MEDIUM模式下的信号映射、LVDS差分传输原理,并强调了屏蔽层处理与端接电阻等关键硬件设计细节。文章结合实战经验,提供了常见图像传输问题的排查思路,是工业视觉领域高速图像传输的实用指南。

weixin_28318011的博客 888

Pytest 常见问题及其解决方案

Pytest 是一个强大且灵活的测试框架,但初学者在使用过程中难免会遇到各种问题。希望通过这篇文章,你能更好地应对常见的挑战,写出更高效、更稳定的测试代码。测试不是负担,而是保障。写好测试不仅能提高代码质量,还能让你在面对变更时更加从容自信。

qq_52137592的博客 899

一种基于 JEP 和可配置公式实现用户自定义字段的解决方案

一种基于 JEP 和可配置公式实现用户自定义字段的解决方案 一、 简介 A: 介绍 JEP(Java Expression Parser) 用于解析和计算表达式,核心功能就是计算公式的解析和结果的计算。 在JEP 2.4.1版本之前未符合GPLv3 协议的免费开源包。 JEP 支持用户自定义函数、常量、变量,在JEP中已经包含了大量可使用的通用数学公式和常量,可以满足绝大多数的数...

chou_out_man的博客 2257

SAP ABAP CDS View 里的日期函数

摘要:本文系统介绍了ABAP CDS日期函数在企业级应用中的关键作用,包括账龄计算、合同续期等业务场景。重点解析了DATS_IS_VALID、DATS_DAYS_BETWEEN等核心函数的语义和使用边界,特别强调on_error四种异常处理策略的选择逻辑。针对系统日期获取,对比了经典CDS的参数注入和View Entity会话变量两种方式。文章还提供了完整可运行的示例代码(包含CDS视图和ABAP程序),帮助开发者快速验证不同版本下的函数行为差异,确保在实际项目中正确应用这些日期处理函数。(149字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 378

Java设计模式 -24- 解释器模式(Interpreter 模式)

Java设计模式 -23- 解释器模式(Interpreter 模式)前言 前言 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式是 GoF 设计模式中最为庞大的一类,它包含以

Android系统工程师--小馬佩德罗 723

OsgEarth —— 笔记1 - 创建地球的earth文件

效果         正文      1、准备一张全球的渲染图(tif格式)、一张全球的高程图(tif格式)        2、创建并编写.earth文件           在步骤1目录下创建china-simple.earth,并将如下内容写入。 <map name="Globe" type="geocentric" version="2"> <!-- 全球影像图 --> <image name="GlobeImage" driver="gdal"> &l

7681

【报错】(pycharm运行程序)OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败。 Error loading

1 报错 OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败。 Error loading 2 分析原因 通过 activate Distance 进行自己创建的 Distance 虚拟环境中,输入python会显示环境中python的版本信息,再依次import,显然不会报错。 这是因为在Anaconda的环境下有支持 import torch 的 dll,而在PyCharm中使用的是自己创建的新环境,还缺少相应支持的dll,仅需在PyCharm中配置环境变量。.

静谧、淡雅 8620

jep 使用方法与简介

1什么是jep JEP是Java expression parser的简称,即java表达式分析器,Jep是一个用来转换和计算数学表达式的java库。通过这个程序包,用户可以以字符串的形式输入一个、任意的公式,然后快速地计算出结果。Jep支持用户自定义变量、常量和函数。包括许多常用的数学函数和常。 简单的来说,就是可以用算术运算符代替之前的java的公式,显示和逻辑编写更加清晰简单 2使用方法 2...

youbai5775的博客 1万+

从询价到回款:一篇讲透 SAP SD 销售与分销的实战入门指南

摘要: SAP SD(Sales and Distribution)模块是SAP ERP中管理销售与分销的核心组件,贯穿从订单到回款(Order-to-Cash)的全流程。其核心价值在于将销售业务结构化,通过主数据(客户、物料、定价)和交易单据(订单、交货、发票)实现流程可审计、可自动化。SD模块与物流(MM)、生产(PP)、财务(FI)深度集成,涵盖定价策略、信用控制、发运管理、国际贸易等复杂场景。关键设计包括条件技术(Condition Technique)实现灵活定价,单据流(Document Flo

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 256

如何在Java中执行Python模块?从认识JEP库开始

从我的实践来讲,我遇到的上一个挑战是,当基础应用引擎是Java的时候,我按常理应该添加一个新的机器学习功能。但是,这里的关键却是,ML功能是在Python里面。那么我们要怎么做呢?我们应用什么样的解决方案来完成这个任务?其中一个工作方案是在docker中运行这个服务。或者我们可以找到另一个更有效的有利于生产的解决方案通过Jep库(JavaEmbeddedPython)直接从Java代码中执行python代码。下面是GitHub上的FAQ中的一些引文。关闭该Interpreter实例。...

u013643074的博客 3877

CAPL控制程控电源

汽车电子测试过程中,除了实车测试,还有台架测试,在进行台架测试时,都需要通过电源来模拟汽车电瓶给ECU供电,如果要进一步进行比较高效的压力测试或自动化测试,就需要用到程控电源,所以本章主要介绍CAPL是如何来控制程控电源的。

测试领域技术分享 4387

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java中JCP, JEP, JLS, JSR是什么

Java中常见的JCP, JEP, JLS, JSR代表什么

7me 4597

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jep的使用

参考jep官网:http://www.singularsys.com/jep/ Jep Java只用几行代码解析和评估数学表达式。此程序包允许您的用户输入公式作为字符串,并立即对其进行评估。Jep支持用户定义的变量,常量和函数。包括许多常见的数学函数和常数。 那么啰嗦,说白了就是支持自定义函数,传入数据,计算出结果,而且很快,精度自己定义. 代码演示: <depe...

晓梦初醒的博客 8598

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

jep java_jep-java-3.4-trial

jep-java-3.4-trial, 0 , 2010-10-31jep-java-3.4-trial\bin, 0 , 2010-10-31jep-java-3.4-trial\build, 0 , 2010-10-31jep-java-3.4-trial\build\com, 0 , 2010-10-31jep-java-3.4-trial\build\com\singularsys, 0 ...

weixin_32139249的博客 364

【Java】 JEP 解析数学表达式计算指标—拯救大物实验计算

JEP 提供了强大的功能,使得在 Java 中进行复杂数学计算变得简单高效。无论是科学计算、工程应用还是数据分析,JEP 都能为开发者提供便利。

weixin_53132064的博客 912

你知道Java中的JCP, JEP, JLS, JSR是什么意思吗?

使用JSR圈定标准范围以后就可以提供给JDK团队成员进行开发, 圈定的范围通常是JAVA相关的, 同时又不会成为Java核心技术(Java SE/EE Core)的一部分.,一个标准的JSR课题通常是一个相对成熟的技术。Java Language Specification的缩写,意为Java语法规范,于指出Java的语法标准和一些规则, 这些规则包括了合规及不合规程序的说明. 规范同时指出了程序的含义并说明了运行后将发生什么。JEP用于探索新的一些想法,一般比JSR更为早期,用于前期的探索,是用于收集。

2873

【JDK】JCP, JEP, JLS, JSR介绍

JCPJava社区标准过程1998JCPJavaJCPJavaJCPJSR。

Java技术栈,分享不断学习、不断超越、不断积累的历程! 1361

解析字符串公式

解析字符串公式-推荐第一种

洛柒 1782

JAVA使用JEP进行动态公式计算

JAVA使用JEP进行公式计算 1.场景描述 在工作中有遇到需要在页面编辑公式,需要后台进行计算,公式中涉及到项目中的基础数据测点,计算时需要动态的替换到测点数据,对公式进行计算得出结果。 2.分析处理 2.1结合场景,使用JEP进行计算,引入依赖 <dependency> <groupId>jep</groupId> <artifactId>jep</artifac

晓二当家的博客 3269

jep在java的SpringBoot中的使用

jep JEP是Java expression parser的简称,即java表达式分析器,Jep是一个用来转换和计算数学表达式的java库。通过这个程序包,用户可以以字符串的形式输入一个、任意的公式,然后快速地计算出结果。Jep支持用户自定义变量、常量和函数。包括许多常用的数学函数和常。 一、在pom文件中引jep的jar包 <dependency> <groupId&g...

weixin_43231872的博客 2572

JEP:Java表达式分析器

JEP 是一个用于解析和计算数学表达式的 Java 类库。通过使用这个包你可以把公式看 作字符串并快速计算它们。其中内置了大量公共的数学函数和常量供用户使用。另外,你也 可以通过自定义变量、常量、函数等方式扩展 JEP。 使用 JEP 计算一个字符串表达式包括两个步骤,如下图所示。首先是解析表达式,从 字符串结构解析为树形结构。表达式的树形结构表示允许接下来的简单、快速的表达式计算。 文档:Jep说明文档_jep,javajep-Java文档类资源-优快云下载 测.

LEEMER 2667

java 使用JEP解析字符串计算公式 求值(附带自定义函数编写)

1.增加jep依赖 <dependency> <groupId>org.scijava</groupId> <artifactId>jep</artifactId> <version>2.4.2</version> </dependency> 2.计算公式 JEP本...

李虹柏的博客 7880
上一篇: 指令重排与更安全地单例模式创建,加深理解
下一篇: feign远程调用方法时,请求需要携带信息的问题
happystudy_neu
博客等级 码龄4年 1140粉丝 43原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值