我必须从D / B中检索一组列值并将其作为条件检查。
例如,我会在D / B列中添加"value > 2"
,"4 < value < 6"
等字符串。 (值是一直比较的值)。我将在我的代码中声明一个变量值,我应该评估这个条件。
int value = getValue();
if (value > 2) //(the string retrieved from the D/B)
doSomething();
我该怎么做?任何帮助都是很受欢迎的。感谢。
答案 0 :(得分:32)
以下是使用标准(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
}
}
答案 1 :(得分:1)
这不会是微不足道的:您需要一个解析器来处理数据库中使用的表达式语言。如果它是一些标准的,指定良好的语言,那么你可能能够在互联网上找到一个,但如果它是内部的东西,那么你可能需要编写自己的(可能使用像ANTLR这样的解析器生成器。)< / p>
javax.script包中包含一些用于集成外部脚本引擎(如Javascript解释器)的工具。另一种想法是引入脚本引擎并将表达式提供给它。
答案 2 :(得分:1)
您基本上是在评估脚本表达式。根据表达式中允许的内容,您可以使用非常简单的东西(标识组的正则表达式)或非常复杂(嵌入javascript引擎?)。
我假设您正在查看简单的案例,其中表达式为: [boundary0] [operator]“value”[operator] [boundary1]
可能省略[boundary] [operator]组中的一个,但不是两个。 (如果两者都是礼物,操作员应该是相同的)
我会使用正则表达式来捕获组。
类似于:(?:( \ d +)\ s *([&lt;&gt;])\ s *)?value(?:\ s *([&lt;&gt;])\ s *(\ d + ))?
然后: boundary1 = group(1); operator1 = group(2); operator2 = group(3); boundary2 = group(4)
答案 3 :(得分:0)
最新版本的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();
}
答案 4 :(得分:0)
您应该尝试通过执行类似
的操作来解析if语句中的字符串if(parseMyString(getValue()))
doSomething();
在parseMyString中可以确定您需要为条件评估的内容。如果您不知道如何创建解析器,请查看:http://www.javapractices.com/topic/TopicAction.do?Id=87
答案 5 :(得分:0)
为了最大限度地灵活地评估条件,请使用专为嵌入而设计的脚本语言,例如MVEL可以解析和评估简单条件表达式,就像问题中那样。
使用MVEL比在Java 1.6+中使用Scripting引擎(特别是使用JavaScript)有一个巨大的优势:使用MVEL,您可以编译脚本到字节码,使他们的评估更加高效运行时。
答案 6 :(得分:0)
这本身并不回答你的问题;它提供了可能产生相同结果的替代解决方案。
不是使用定义条件的伪代码存储单个数据库列,而是创建一个表,其中模式定义必须满足的条件类型以及这些条件的值。这简化了对这些条件的编程评估,但如果您有各种类型的条件需要评估,它可能会变得复杂。
例如,您可能有一个如下所示的表。
CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME | ETC.
______________________________________________________
1 | 2 | NULL | NULL | ...
2 | 4 | 6 | NULL | ...
这些行条目分别映射到规则value > 2
和6 > value > 4
。
与您提供的方法相比,这可以带来许多好处。
答案 7 :(得分:-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块中以执行条件操作。在上面的代码中,您可以传递任何字符串来代替此示例中传递的内容