1. Overview
1.概述
In this tutorial, we’ll discuss various approaches to evaluate a math expression using Java. This feature could come in handy in projects where we want to evaluate math expressions provided in string format.
在本教程中,我们将讨论使用Java评估数学表达式的各种方法。在我们要评估以字符串格式提供的数学表达式的项目中,这一功能可能会派上用场。
To begin with, we’ll discuss a few third-party libraries and their usage. Next, we’ll see how we can use the built-in Java Scripting API to achieve this task.
首先,我们将讨论几个第三方库和它们的用法。接下来,我们将看到我们如何使用内置的Java Scripting API来实现这一任务。
2. exp4j
2.exp4j
exp4j is an open-source library that can be used to evaluate mathematical expressions and functions. The library implements Dijkstra’s Shunting Yard Algorithm, a method for parsing mathematical expressions specified in infix notation.
exp4j是一个开源的库,可用于评估数学表达式和函数。该库实现了Dijkstra’s Shunting Yard Algorithm,一种用于解析以infix notation指定的数学表达式的方法。
In addition to using standard operators and functions, exp4j allows us to create custom operators and functions.
除了使用标准的运算符和函数外,exp4j还允许我们创建自定义的运算符和函数。
2.1. Adding the Maven Dependency
2.1.添加Maven依赖项
To use exp4j, we’ll need to add the Maven dependency in our project:
要使用exp4j,我们需要在项目中添加Maven依赖项。
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
2.2. Evaluating Simple Expressions
2.2.评估简单的表达式
We can evaluate a simple math expression provided in String format:
我们可以评估一个以String格式提供的简单数学表达式。
@Test
public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("3+2").build();
double result = expression.evaluate();
Assertions.assertEquals(5, result);
}
In the above code snippet, we first create an instance of ExpressionBuilder. Then we assign it to an Expression reference, which we use to evaluate our expression.
在上面的代码片段中,我们首先创建了一个ExpressionBuilder的实例。然后我们将其分配给一个Expression引用,我们用它来评估我们的表达式。
2.3. Using Variables in Expressions
2.3.在表达式中使用变量
Now that we know how to evaluate simple expressions, let’s add some variables to our expression:
现在我们知道了如何评估简单的表达式,让我们给我们的表达式添加一些变量。
@Test
public void givenTwoVariables_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("3x+2y")
.variables("x", "y")
.build()
.setVariable("x", 2)
.setVariable("y", 3);
double result = expression.evaluate();
Assertions.assertEquals(12, result);
}
In the above example, we introduce two variables, x, and y, using the variables method. We can add as many variables as we need in the expression using this method. Once we’ve declared the variables, we can assign values to them using the setVariable method.
在上面的例子中,我们使用variables方法引入两个变量,x,和y,。我们可以使用这个方法在表达式中添加我们需要的任意数量的变量。一旦我们声明了变量,我们就可以使用setVariable方法给它们赋值。
2.4. Evaluating Expressions Containing Math Functions
2.4.评估含有数学函数的表达式
Let’s now see a short example of how we can evaluate some standard math functions:
现在让我们看一个简短的例子,看看我们如何评估一些标准的数学函数。
@Test
public void givenMathFunctions_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("sin(x)*sin(x)+cos(x)*cos(x)")
.variables("x")
.build()
.setVariable("x", 0.5);
double result = expression.evaluate();
Assertions.assertEquals(1, result);
}
3. Javaluator
3.Javaluator
Javaluator is another independent and lightweight library that is available for free. Like exp4j, Javaluator is also used to evaluate infix expressions.
Javaluator是另一个独立的、轻量级的库,可以免费使用。与exp4j一样,Javaluator也被用于评估infix表达式。
3.1. Adding the Maven Dependency
3.1.添加Maven依赖项
We can use the following Maven dependency to use Javaluator in our project:
我们可以使用以下Maven依赖性来在我们的项目中使用Javaluator。
<dependency>
<groupId>com.fathzer</groupId>
<artifactId>javaluator</artifactId>
<version>3.0.3</version>
</dependency>
3.2. Evaluating Simple Expressions
3.2.评估简单的表达式
To evaluate expressions using Javaluator, we first need to create an instance of DoubleEvaluator:
为了使用Javaluator评估表达式,我们首先需要创建一个DoubleEvaluator的实例。
@Test
public void givenExpression_whenCallEvaluateMethod_thenSuccess() {
String expression = "3+2";
DoubleEvaluator eval = new DoubleEvaluator();
Double result = eval.evaluate(expression);
Assertions.assertEquals(5, result);
}
3.3. Evaluating Expressions Containing Variables
3.3.对含有变量的表达式进行评估
To evaluate expressions containing variables, we use the StaticVariableSet:
为了评估包含变量的表达式,我们使用StaticVariableSet。
@Test
public void givenVariables_whenCallEvaluateMethod_thenSuccess() {
String expression = "3*x+2*y";
DoubleEvaluator eval = new DoubleEvaluator();
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
variables.set("x", 2.0);
variables.set("y", 3.0);
Double result = eval.evaluate(expression, variables);
Assertions.assertEquals(12, result);
}
We then use the StaticVariableSet#set method to assign values to the variables.
然后我们使用StaticVariableSet#set方法来给变量赋值。
3.4. Evaluating Expressions Containing Math Functions
3.4.评估含有数学函数的表达式
We can also solve expressions containing math functions using the Javaluator library:
我们还可以使用Javaluator库解决包含数学函数的表达式。
@Test
public void givenMathFunction_whenCallEvaluateMethod_thenSuccess() {
String expression = "sin(x)*sin(x)+cos(x)*cos(x)";
DoubleEvaluator eval = new DoubleEvaluator();
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
variables.set("x", 0.5);
Double result = eval.evaluate(expression, variables);
Assertions.assertEquals(1, result);
}
4. The Java Scripting API
4.Java Scripting API
Now that we’ve discussed third-party libraries, let’s now discuss how we can achieve this using the built-in API. Java already comes with a small but powerful scripting API. All the classes and interfaces of this API are in the javax.script package.
现在我们已经讨论了第三方库,现在让我们来讨论一下如何使用内置的API来实现这个目标。Java已经配备了一个小而强大的脚本API。这个API的所有类和接口都在javax.script包中。
It contains the ScriptEngineManager and ScriptEngine interfaces that allow us to evaluate JavaScript. Before Java 8, Java came with the Rhino engine. However, from Java 8 onward, Java comes with the newer and more powerful Nashorn engine.
它包含ScriptEngineManager和ScriptEngine接口,允许我们评估JavaScript。在Java 8之前,Java配备的是Rhino引擎。然而,从Java 8开始,Java配备了更新、更强大的Nashorn引擎。
4.1. Getting ScriptEngine Instance
4.1.获取ScriptEngine实例
To create a ScriptEngine, we first have to create an instance of ScriptEngineManager. Once we have the instance, we need to call the ScriptEngineManager#getEngineByName method to get the ScriptEngine:
要创建一个ScriptEngine,我们首先要创建一个ScriptEngineManager的实例。一旦我们有了这个实例,我们需要调用ScriptEngineManager#getEngineByName方法来获取ScriptEngine。
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
Note that Nashorn is the default JavaScript engine that comes packaged with the JDK.
请注意,Nashorn是随JDK打包的默认JavaScript引擎。
4.2. Evaluating Simple Expressions
4.2.评估简单的表达式
We can now use the above scriptEngine instance to call the ScriptEngine#eval method:
我们现在可以使用上述scriptEngine实例来调用ScriptEngine#eval方法。
String expression = "3+2";
Integer result = (Integer) scriptEngine.eval(expression);
Assertions.assertEquals(5, result);
4.3. Evaluating Expressions Containing Variables
4.3.对含有变量的表达式进行评估
To evaluate expressions containing variables we need to declare and initialize variables:
为了评估包含变量的表达式,我们需要声明和初始化变量。
String expression = "x=2; y=3; 3*x+2*y;";
Double result = (Double) scriptEngine.eval(expression);
Assertions.assertEquals(12, result);
Since we are using the JavaScript engine, we can directly add variables to the expressions as we do in JavaScript.
由于我们使用的是JavaScript引擎,我们可以像在JavaScript中那样直接向表达式添加变量。
Note – JavaScript doesn’t have direct methods to perform math operations and requires access to the Math object. Thus, we cannot solve math expressions using the Java Scripting API.
注意 – JavaScript没有直接的方法来进行数学运算,需要访问Math对象。因此,我们无法使用Java Scripting API来解决数学表达式。
5. Conclusion
5.总结
In this article, we’ve seen various techniques for evaluating math expressions using Java.
在这篇文章中,我们已经看到了使用Java评估数学表达式的各种技术。
As always, the complete code for this example is available over on GitHub.
一如既往,本例的完整代码可在GitHub上获得over。