-2

I am learning Java now and don't know how to convert an input string(such as "4>1") to get a boolean return.

The goal that I want to achieve is that, let Java return boolean(true/false) based on the user input, which is in String?

For example, I tried to get a return value of "true" for input "!(4>=10)".

azro
  • 53,056
  • 7
  • 34
  • 70
Suye Shen
  • 11
  • 2
  • 1
    What have you tried so far? Can you paste your code? – Pijotrek Aug 17 '17 at 07:19
  • Maybe see here for more informations: https://stackoverflow.com/questions/7143343/is-there-a-java-equivalent-of-the-python-eval-function – NatNgs Aug 17 '17 at 07:20
  • 1
    Okay sorry but I think I still have some problems with this..;_; For now, I tried String userInput = input.next(); boolean result = Boolean.valueOf(userInput); System.out.print(result); I typed "4<10" for test and it returns false – Suye Shen Aug 17 '17 at 07:43
  • Please take a look at my Nashorn solution. I am a bit amazed myself, how well it works. :) lol – bvdb Aug 17 '17 at 08:54
  • @SuyeShen, did you find the answer you were looking for? I left an optional answer with simple code example below. – Assafs Aug 17 '17 at 10:37
  • 1
    Try MathParser.org-mXparser. http://mathparser.org/ http://mathparser.org/mxparser-tutorial/evaluating-relations/ Code sample Expression e = new Expression("4>1"); double doubleResult = e.calculate(); boolean boolResult = false; if (doubleResult == 1) boolResult = true; – Leroy Kegan Aug 28 '17 at 11:24
  • MathParser.org-mXparser cannot evaluate logical operators. Only Mathematical operations. – Radhesh Khanna Oct 07 '20 at 11:59

1 Answers1

3

There is no easy answer

For starters there are no easy solutions. I noticed somebody mentioning Boolean.valueOf(...);

The goal of the Boolean.valueOf(String) method is not to evaluate conditions or equations. It is just a simple method to convert a String with value "true" or "false" to a Boolean object.

Anyway, if you want this kind of functionality, you have to set some clear limitations. (note: some equations have no answer: "0/0 = 0/0")

Regex parsing

If you are simply comparing integers with integers, then you could assume that the equations will always be in the following format:

<integer1>[whitespace]<operator>[whitespace]<integer2>

Then, what you could do, is split your string in 3 parts using a regular expression.

public static boolean evaluate(String input)
{
  Pattern compile = Pattern.compile("(\\d+)\\s*([<>=]+)\\s*(\\d+)");
  Matcher matcher = compile.matcher(input);
  if (matcher.matches())
  {
    String leftPart = matcher.group(1);
    String operatorPart = matcher.group(2);
    String rightPart = matcher.group(3);

    int i1 = Integer.parseInt(leftPart);
    int i2 = Integer.parseInt(rightPart);

    if (operatorPart.equals("<")) return i1 < i2;
    if (operatorPart.equals(">")) return i1 > i2;
    if (operatorPart.equals("=")) return i1 == i2;
    if (operatorPart.equals("<=")) return i1 <= i2;
    if (operatorPart.equals(">=")) return i1 >= i2;

    throw new IllegalArgumentException("invalid operator '" + operatorPart + "'");
  }

  throw new IllegalArgumentException("invalid format");
}

Script Engines

Java also supports script engines (e.g. Nashorn and others). These engines can call javascript methods, such as the eval(...) javascript method, which is exactly what you need. So, this is probably a better solution.

public static boolean evaluate(String input)
{
  try
  {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    Object result = engine.eval("eval('" + input + "');");
    return Boolean.TRUE.equals(result);
  }
  catch (ScriptException e)
  {
    throw new IllegalArgumentException("invalid format");
  }
}

This solution can handle more complicated input, such as "!(4>=10)".

Note: for security reasons, you may want to strip specific characters from the user input. (e.g. the ' character)

Community
  • 1
  • 1
bvdb
  • 22,839
  • 10
  • 110
  • 123