1. Обзор
В этом руководстве мы обсудим различные подходы к оценке математического выражения с использованием Java. Эта функция может пригодиться в проектах, где мы хотим оценить математические выражения, представленные в строковом формате.
Для начала мы обсудим несколько сторонних библиотек и их использование. Далее мы увидим, как мы можем использовать встроенный API сценариев Java для решения этой задачи.
2. exp4j
exp4j — это библиотека с открытым исходным кодом, которую можно использовать для вычисления математических выражений и функций. Библиотека реализует алгоритм Дейкстры Shunting Yard Algorithm, метод разбора математических выражений, заданных в инфиксной нотации .
Помимо использования стандартных операторов и функций, exp4j позволяет нам создавать собственные операторы и функции.
2.1. Добавление зависимости Maven
Чтобы использовать exp4j, нам нужно добавить зависимость Maven в наш проект:
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
2.2. Оценка простых выражений
Мы можем оценить простое математическое выражение, представленное в формате String :
@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);
}
В приведенном выше примере мы вводим две переменные, 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);
}
3. Явалюатор
Javaluator — еще одна независимая и легкая библиотека, доступная бесплатно. Как и exp4j, Javaluator также используется для вычисления инфиксных выражений .
3.1. Добавление зависимости Maven
Мы можем использовать следующую зависимость Maven для использования Javaluator в нашем проекте:
<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);
}
Затем мы используем метод StaticVariableSet#set
для присвоения значений переменным.
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. API сценариев Java
Теперь, когда мы обсудили сторонние библиотеки, давайте теперь обсудим, как мы можем добиться этого с помощью встроенного API. Java уже поставляется с небольшим, но мощным API сценариев. Все классы и интерфейсы этого API находятся в пакете javax.script
.
Он содержит интерфейсы ScriptEngineManager
и ScriptEngine
, которые позволяют нам оценивать JavaScript. До Java 8 Java поставлялась с движком Rhino .
Однако, начиная с Java 8, Java поставляется с более новым и мощным движком Nashorn .
4.1. Получение экземпляра ScriptEngine
Чтобы создать ScriptEngine
, нам сначала нужно создать экземпляр ScriptEngineManager
. Получив экземпляр, нам нужно вызвать метод ScriptEngineManager#getEngineByName
, чтобы получить ScriptEngine
:
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
Обратите внимание, что Nashorn
— это движок JavaScript по умолчанию, который поставляется вместе с JDK.
4.2. Оценка простых выражений
Теперь мы можем использовать приведенный выше экземпляр scriptEngine
для вызова метода 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.
Как всегда, полный код этого примера доступен на GitHub .