Boolean Expression Evaluation in Java
Asked Answered
A

10

13

I'm looking for a relatively simpler (when compared with writing a parser) way to evaluate boolean expressions in Java, and I do not want to use the JEP library.

I have a String expression like: (x > 4 || x < 8 && p > 6) and my aim is to replace the variables with values.

Is there a way by which I can evaluate this expression?

Bear in mind that this can be any level deep so writing a parser would be very complex.

Allusion answered 15/11, 2009 at 5:26 Comment(0)
C
6

You could use the scripting engine in Java6 and the choose any of the popular scripting languages like Scala, Ruby, Python, Groovy, and Javascript. Than all you have to do is make sure the expression you want to evaluate is in the right language. Groovy is probably the easiest and will integrate best.

I have used this method successfully for a feature offering capabilities much like a formula / calculated column in a popular spreadsheet application.

Cottage answered 15/11, 2009 at 5:53 Comment(0)
E
16

Use Apache Commons Jexl; which is exactly designed for such requirement.

http://commons.apache.org/jexl/

Egger answered 15/11, 2009 at 5:47 Comment(1)
+1 Here's a good example of how it's used. commons.apache.org/jexl/reference/examples.htmlChemise
F
7

Using jexl (http://commons.apache.org/jexl/), you can accomplish this like this

    JexlEngine jexl = new JexlEngine();
    jexl.setSilent(true);
    jexl.setLenient(true);

    Expression expression = jexl.createExpression("(a || b && (c && d))");
    JexlContext jexlContext = new MapContext();

    //b and c and d should pass
    jexlContext.set("b",true);
    jexlContext.set("c",true);
    jexlContext.set("d",true);

    assertTrue((Boolean)expression.evaluate(jexlContext));

    jexlContext = new MapContext();

    //b and c and NOT d should be false
    jexlContext.set("b",true);
    jexlContext.set("c",true);

    //note this works without setting d to false on the context
    //because null evaluates to false

    assertFalse((Boolean)expression.evaluate(jexlContext));
Forehanded answered 20/9, 2012 at 14:24 Comment(2)
The one issue I had with jexl was its prioritization. I have a case where I need to evaluate || before I evaluate &&. So the above expression turns into (a||b)&&(c&&d). In jexl, using a context of just 'a' would evaluate to true.Melatonin
Just for reference: I tried the example with your expression of (a||b)&&(c&&d) and it seems fixed. Just 'a' evaluates to 'false', which is correct.Adlib
C
6

You could use the scripting engine in Java6 and the choose any of the popular scripting languages like Scala, Ruby, Python, Groovy, and Javascript. Than all you have to do is make sure the expression you want to evaluate is in the right language. Groovy is probably the easiest and will integrate best.

I have used this method successfully for a feature offering capabilities much like a formula / calculated column in a popular spreadsheet application.

Cottage answered 15/11, 2009 at 5:53 Comment(0)
P
1

Here is the latest resources for expression evaluation framework

The information page is at http://expressionoasis.vedantatree.com/

Pillow answered 29/10, 2010 at 18:33 Comment(0)
T
0

JUEL provides an implementation of Java's Unified Expression Language without being explicitly tied to JSP. Here's its Quick Start guide, expression evaluation (#3 on that page) is the part you're interested in.

Alternatively, Spring 3.0 provides its own (though somewhat similar) expression language. This option only makes sense if you're already using Spring, though - I wouldn't pull it in just for EL.

Title answered 15/11, 2009 at 5:38 Comment(0)
U
0

There is a API available at http://lts.online.fr/dev/java/math.evaluator/

Example:

MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)");
m.addVariable("x", 15.1d);
System.out.println( m.getValue() );
Understandable answered 29/1, 2010 at 10:59 Comment(1)
This link does not seem to be working, at least at the time of writing. Also, does this library support comparison operators and boolean values like the OP asked?Doubs
M
0

Try http://code.google.com/p/xpressionengine/ for open source implementation

Michelle answered 21/3, 2010 at 15:8 Comment(0)
D
0

I found the libraries listed here too complicated for my needs. I ended up using Fscript: http://fscript.sourceforge.net/

Deceive answered 29/12, 2011 at 23:22 Comment(0)
P
0

try Janino http://docs.codehaus.org/display/JANINO/Home It is very simple to use eg (taken from http://docs.codehaus.org/display/JANINO/Basic):

// Compile the expression once; relatively slow.
ExpressionEvaluator ee = new ExpressionEvaluator(
    "c > d ? c : d",                     // expression
    int.class,                           // expressionType
    new String[] { "c", "d" },           // parameterNames
    new Class[] { int.class, int.class } // parameterTypes
);

// Evaluate it with varying parameter values; very fast.
Integer res = (Integer) ee.evaluate(
    new Object[] {          // parameterValues
        new Integer(10),
        new Integer(11),
    }
);
System.out.println("res = " + res);
Provitamin answered 9/8, 2013 at 9:21 Comment(0)
B
0

You could try this library https://github.com/Shy-Ta/expression-evaluator-demo - the read me has a fair number of examples. The library uses java and groovy.

In addition to supporting this use case, it also supports a lot of other excel like functions. Also, it is very simple to add new functions as demonstrated in the example.

      ExpressionsEvaluator evalExpr = ExpressionsFactory.create("(x > 4 || x < 8 && p > 6)");  
      Map<String, Object> variables = new HashMap<String, Object>();  
      variables.put("x", 100);  
      variables.put("p", 10);
      evalExpr.eval();
Bookbinder answered 1/1, 2015 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.