繁体   English   中英

将字符串评估为条件Java

[英]Evaluate String as a condition Java

我必须从D / B检索一组列值并将其作为条件进行检查。

例如,我将在D / B列中使用诸如"value > 2""4 < value < 6"类的字符串。 (值是一直比较的值)。 我将在代码中声明一个变量值,我应该评估这种情况。

int value = getValue();
if (value > 2)  //(the string retrieved from the D/B)
  doSomething();

我怎样才能做到这一点?? 任何帮助都受到赞赏。 谢谢。

这是使用标准(Java 1.6+)脚本库的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Test {

    public static void main(String[] args) throws Exception {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("JavaScript");

        engine.eval("value = 10");
        Boolean greaterThan5 = (Boolean) engine.eval("value > 5");
        Boolean lessThan5 = (Boolean) engine.eval("value < 5");

        System.out.println("10 > 5? " + greaterThan5); // true
        System.out.println("10 < 5? " + lessThan5); // false
    }
}

这不会太简单:您需要一个解析器来解析数据库中使用的表达语言。 如果这是一种标准的,经过良好指定的语言,则可以在Internet上找到一种语言,但是如果是内部语言,则可能需要编写自己的语言(也许使用诸如ANTLR的解析器生成器)。

javax.script软件包包含一些用于集成外部脚本引擎(如Java解释器)的工具。 另一种想法是引入脚本引擎并将表达式提供给它。

您基本上是在评估脚本表达式。 根据该表达式所允许的内容,您可以摆脱一些非常简单的事情(用正则表达式标识组)或复杂的事情(嵌入一个javascript引擎?)。

我假设您正在看一个简单的情况,表达式是:[boundary0] [operator]“ value” [operator] [boundary1]

其中[边界] [操作员]组中的一个,但不是两个都可以省略。 (如果两者都存在,则运算符应相同)

对于捕获组,我将使用正则表达式。

类似于:(?:(\\ d +)\\ s *([<>])\\ s *)?value(?:\\ s *([<>])\\ s *(\\ d +))?

然后:boundary1 = group(1); operator1 = group(2); operator2 = group(3); 边界2 =组(4)

最新版本的Java(Java 7)允许在字符串上使用Switch Case语句,如果可能的变体不多,则可以执行以下操作或类似操作:

int value = getValue();
switch(myString) {
  case "value > 2" : if (value > 2) {  doSomething();} break;
  case "4 < value < 6" : if (value > 4 && value < 6) {  doSomethingElse();} break;
  default : doDefault();
}

您应该尝试执行以下操作来解析if语句中的字符串

if(parseMyString(getValue()))
    doSomething();

在parseMyString中可以确定您需要对条件进行评估的内容。 如果您不知道如何创建解析器,请查看: http : //www.javapractices.com/topic/TopicAction.do?Id=87

为了最大程度地评估条件,请使用专为嵌入而设计的脚本语言,例如MVEL可以解析和评估简单的条件表达式,例如问题中的条件表达式。

与使用Java 1.6+(特别是JavaScript)中的脚本引擎相比,使用MVEL具有一个巨大的优势:使用MVEL,您可以将脚本编译为字节码,从而使它们的评估在运行时更加高效。

这本身并不能回答您的问题; 它提供了可能影响相同结果的替代解决方案。

而不是使用定义条件的伪代码存储单个数据库列,而是创建一个表,在该表中,架构定义必须满足的条件类型以及这些条件的值。 这简化了对这些条件的程序评估,但如果要评估的条件类型多种多样,则可能会变得复杂。

例如,您可能有一个如下所示的表。

CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME  |   ETC.
______________________________________________________
      1      |    2    |   NULL  |   NULL    |   ...
      2      |    4    |    6    |   NULL    |   ...

这些行条目分别映射到规则value > 26 > value > 4

与您提供的方法相比,这可带来许多好处。

  • 改善性能和清洁度
  • 您的条件可以在数据库级别评估,并且可以用来过滤查询
  • 您不必担心处理伪代码语法已损坏的情况

除了使用Java 7之外,一种很好的方法是使用枚举。 声明枚举,如下所示

上面的枚举有一个常量集合,其值设置为您希望从数据库返回的字符串。 由于您可以在切换情况下使用枚举,因此其余代码变得容易

enum MyEnum
{
    val1("value < 4"),val2("4<value<6");
    private String value;

    private MyEnum(String value)
    {
        this.value = value;
    }
}


public static void chooseStrategy(MyEnum enumVal)
{   
    int value = getValue();
    switch(enumVal)
    {
        case val1:
        if(value > 2){}
        break;
        case val2:
        if(4 < value && value < 6) {}
        break;
        default:
    }
}

public static void main(String[] args)
{
    String str = "4<value<6";
    chooseStrategy(MyEnum.valueOf(str));
}

您所要做的就是将字符串传递给enum.valueof方法,它将返回适当的枚举,该枚举放入switch case块中以执行条件操作。 在上面的代码中,您可以传递任何字符串来代替本示例中传递的字符串

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM