Java Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

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.

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.

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.

In addition to using standard operators and functions, exp4j allows us to create custom operators and functions.

2.1. Adding the Maven Dependency

To use exp4j, we'll need to add the Maven dependency in our project:

<dependency>
    <groupId>net.objecthunter</groupId>
    <artifactId>exp4j</artifactId>
    <version>0.4.8</version>
</dependency>

2.2. Evaluating Simple Expressions

We can evaluate a simple math expression provided in String format:

@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.

2.3. Using Variables in Expressions

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.

2.4. Evaluating Expressions Containing Math Functions

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

Javaluator is another independent and lightweight library that is available for free. Like exp4j, Javaluator is also used to evaluate infix expressions.

3.1. Adding the Maven Dependency

We can use the following Maven dependency to use Javaluator in our project:

<dependency>
    <groupId>com.fathzer</groupId>
    <artifactId>javaluator</artifactId>
    <version>3.0.3</version>
</dependency>

3.2. Evaluating Simple Expressions

To evaluate expressions using Javaluator, we first need to create an instance of 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

To evaluate expressions containing variables, we use the 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.

3.4. Evaluating Expressions Containing Math Functions

We can also solve expressions containing math functions using the Javaluator library:

@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

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.

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.

4.1. Getting ScriptEngine Instance

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:

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");

Note that Nashorn is the default JavaScript engine that comes packaged with the JDK.

4.2. Evaluating Simple Expressions

We can now use the above scriptEngine instance to call the ScriptEngine#eval method:

String expression = "3+2";
Integer result = (Integer) scriptEngine.eval(expression);
Assertions.assertEquals(5, result);

4.3. Evaluating Expressions Containing Variables

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.

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.

5. Conclusion

In this article, we've seen various techniques for evaluating math expressions using Java.

As always, the complete code for this example is available over on GitHub.

Java bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Comments are closed on this article!