在Java中,如何动态创建关系表达式,执行它并获得最终的布尔结果

时间:2013-06-23 07:48:31

标签: java

我在数据库中有2个字段,例如senti_opsenti_score这两个都是字符串。 senti_score包含值为Double的字符串,即25.0030.50等,而senti_op包含关键字符号的字符串,如>=,{{1} },>等。

在Java中,我想这样做:

  • 对于< senti_op,我希望逻辑表达式为:>=
  • 代表if ("some double value" >= senti_score),我想要<

我正在尝试形成这些关系表达式并将其if ("some double value" < senti_score)结果稍后用于代码的其他部分。

请提供可编译的Java示例代码。我试图避免为每个运算符使用字符串比较编写大量的if-else语句,并评估这些值并寻找小而有效的解决方案。

我对这些事情很陌生,并感谢你的帮助。

3 个答案:

答案 0 :(得分:4)

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

public class SimpleTests {

    public static void main(String[] args) {
            ScriptEngineManager mgr = new ScriptEngineManager();
            ScriptEngine engine = mgr.getEngineByName("JavaScript");
            String exp = "some double value"+ senti_op +senti_score;
            try {
                System.out.println(engine.eval(exp));
            } catch (ScriptException e) {

                e.printStackTrace();
            }


    }
}

答案 1 :(得分:1)

未经过测试(包含一些lombok注释和一些guava

@RequiredArgsConstructor
private static enum Operation {
    LESS_OR_EQUAL("<="), GREATER_OR_EQUAL(">="), 
    GREATER(">"), LESS("<"), EQUALS("=");

    @Getter
    final String operation;

    public static Operation parse(final String val) {
        for(final Operation pop : values()) {
            if (pop.getOperation().equals(val)) {
                return pop;
            }
        }
        return null;
    }
}

public boolean handleOperation(final String senti_score, final String senti_op, final Double someDoubleVal) {
    // parse the double
    final Double sentiScore = Doubles.tryParse(senti_score);
    // parse the operation using Operation enum
    final Operation sentiOp = Operation.parse(senti_op);

    // TODO: checks for nullity on both parsed value

    // use a switch to compute result
    switch (sentiOp) {
    case LESS_OR_EQUAL:
        return someDoubleVal.compareTo(sentiScore) <= 1; 
    case GREATER_OR_EQUAL:
        return someDoubleVal.compareTo(sentiScore) >= 1;
    case LESS:
        return someDoubleVal.compareTo(sentiScore) < 1;
    case GREATER:
        return someDoubleVal.compareTo(sentiScore) > 1;
    case EQUAL:
        return someDoubleVal.compareTo(sentiScore) == 0;
    }
    throw new IllegalArgumentException("Unhandled op:" + senti_op);
}

答案 2 :(得分:1)

在Java 7中,您可以避免使用String上的switch语句编写if-else链。

您还应该查看floating point arithmetic。它并不总是像人们期望的那样。

public class SentiEvaluator {

    public boolean evaluate(String sentiOp, String sentiScore, double otherValue) {
        if (sentiOp == null) {
            throw new IllegalArgumentException("Operator must be specified.");
        }
        if (sentiScore == null) {
            throw new IllegalArgumentException("Score must be specified.");
        }

        double score = Double.parseDouble(sentiScore);
        return evaluateJava7(score, sentiOp, otherValue);
    }

    private boolean evaluateJava7(double leftOp, String operator, double rightOp) {
        switch (operator) {
            case "=": return leftOp == rightOp;
            case ">": return leftOp > rightOp;
            case ">=": return leftOp >= rightOp;
            case "<": return leftOp < rightOp;
            case "<=": return leftOp <= rightOp;
            default: throw new IllegalArgumentException("Unknown operator " + operator);
        }
    }

}