1. 概要

このチュートリアルでは、Javaを使用して数式を評価するためのさまざまなアプローチについて説明します。 この機能は、文字列形式で提供される数式を評価するプロジェクトで役立ちます。

まず、いくつかのサードパーティライブラリとその使用法について説明します。 次に、組み込みのJavaスクリプティングAPIを使用してこのタスクを実行する方法を説明します。

2. exp4j

exp4j は、数式や関数の評価に使用できるオープンソースライブラリです。 ライブラリは、Dijkstraの操車場アルゴリズムを実装しています。中置記法で指定された数式を解析するためのメソッドです。

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、の2つの変数を導入します。 このメソッドを使用して、式に必要な数の変数を追加できます。 変数を宣言したら、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

Javaluator は、無料で利用できるもう1つの独立した軽量ライブラリです。 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. JavaスクリプティングAPI

サードパーティのライブラリについて説明したので、組み込みのAPIを使用してこれを実現する方法について説明します。 Javaには、小さいながらも強力なスクリプトAPIがすでに付属しています。 このAPIのすべてのクラスとインターフェースは、javax.scriptパッケージに含まれています。

これには、JavaScriptを評価できるScriptEngineManagerおよびScriptEngineインターフェースが含まれています。 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 は、JDKにパッケージ化されているデフォルトのJavaScriptエンジンであることに注意してください。

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オブジェクトへのアクセスが必要です。 したがって、JavaScriptingAPIを使用して数式を解決することはできません。

5. 結論

この記事では、Javaを使用して数式を評価するためのさまざまな手法を見てきました。

いつものように、この例の完全なコードは、GitHubから入手できます。