1. Обзор
В этом руководстве мы рассмотрим различные подходы к вычислению математических выражений в Java. Эта возможность может быть полезна в проектах, где необходимо обрабатывать математические выражения, представленные в виде строки.
Сначала мы рассмотрим несколько сторонних библиотек и их применение. Затем увидим, как использовать встроенное API Java для выполнения этой задачи.
2. exp4j
exp4j — это библиотека с открытым исходным кодом, которая может использоваться для вычисления математических выражений и функций. Библиотека реализует алгоритм сортировочной станции Дейкстры (Shunting Yard Algorithm) — метод парсинга математических выражений в инфиксной записи.
Кроме стандартных операторов и функций, exp4j позволяет создавать пользовательские операторы и функции.
2.1. Добавление зависимости Maven
Чтобы использовать exp4j, необходимо добавить следующую зависимость в pom.xml проекта:
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
2.2. Вычисление простых выражений
Мы можем вычислить простое математическое выражение, представленное в виде строки:
@Test
public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("3+2").build();
double result = expression.evaluate();
Assertions.assertEquals(5, result);
}
В этом примере сначала создаётся экземпляр ExpressionBuilder. Затем он передаётся в переменную типа Expression, которую мы используем для вычисления выражения.
2.3. Использование переменных в выражениях
Теперь, когда мы умеем обрабатывать простые выражения, давайте добавим переменные:
@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);
}
В этом примере мы используем метод variables, чтобы объявить две переменные — x и y. Затем с помощью setVariable присваиваем им значения. Можно добавлять любое количество переменных.
2.4. Вычисление выражений с математическими функциями
Посмотрим короткий пример, как вычислять выражения с использованием стандартных математических функций:
@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);
}
Здесь вычисляется тригонометрическое тождество: sin²(x) + cos²(x) = 1. Мы задаём переменную x, присваиваем ей значение и выполняем вычисление.
3. Javaluator
Javaluator — это ещё одна независимая и лёгкая библиотека, доступная бесплатно. Как и exp4j, Javaluator используется для вычисления выражений в инфиксной записи.
3.1. Добавление зависимости Maven
Чтобы использовать Javaluator в проекте, добавьте следующую зависимость в pom.xml:
<dependency>
<groupId>com.fathzer</groupId>
<artifactId>javaluator</artifactId>
<version>3.0.3</version>
</dependency>
3.2. Вычисление простых выражений
Для вычисления выражений с помощью 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. Вычисление выражений с переменными
Для выражений с переменными используется 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);
}
Для присвоения значений переменным используется метод set у StaticVariableSet.
3.4. Вычисление выражений с математическими функциями
С помощью библиотеки 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. Java Scripting API
Теперь, когда мы рассмотрели сторонние библиотеки, давайте обсудим, как можно достичь того же с помощью встроенного API. Java уже содержит небольшой, но мощный скриптовый API. Все классы и интерфейсы этого API находятся в пакете javax.script.
Он включает интерфейсы ScriptEngineManager и ScriptEngine, которые позволяют выполнять JavaScript-код. До Java 8 использовался движок Rhino, но начиная с Java 8 используется более современный и мощный движок Nashorn.
4.1. Получение экземпляра ScriptEngine
Чтобы создать ScriptEngine, сначала нужно создать экземпляр ScriptEngineManager. Затем, вызвав метод getEngineByName, получаем нужный движок:
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
Обратите внимание: по умолчанию вместе с JDK поставляется движок JavaScript Nashorn.
4.2. Вычисление простых выражений
Теперь мы можем использовать экземпляр scriptEngine, чтобы вызвать метод eval:
String expression = "3+2";
Integer result = (Integer) scriptEngine.eval(expression);
Assertions.assertEquals(5, result);
4.3. Вычисление выражений с переменными
Чтобы вычислить выражения с переменными, необходимо их объявить и проинициализировать:
String expression = "x=2; y=3; 3*x+2*y;";
Double result = (Double) scriptEngine.eval(expression);
Assertions.assertEquals(12, result);
Так как используется JavaScript-движок, переменные можно добавлять прямо в выражение, как это делается в JavaScript.
В JavaScript отсутствуют прямые функции для математических операций, и для их выполнения нужно использовать объект Math. Поэтому не все математические выражения можно корректно обработать с помощью Java Scripting API.
5. Заключение
В этой статье мы рассмотрели различные подходы к вычислению математических выражений в Java.
Оригинал статьи: https://www.baeldung.com/java-evaluate-math-expression-string