Подтвердить что ты не робот

Оценить String как условие Java

Мне нужно получить набор значений столбцов из D/B и проверить его как условие.

Например, у меня будут строки типа "value > 2", "4 < value < 6" в столбце D/B. (значение такое, которое сравнивается все время). У меня будет значение переменной, указанное в моем коде, и я должен оценить это условие.

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

Как я могу это сделать? Любая помощь - это муце. Спасибо.

4b9b3361

Ответ 1

Вот пример использования стандартной (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
    }
}

Ответ 2

Это не будет тривиально: вам нужен синтаксический анализатор для языка выражений, который используется в вашей базе данных. Если это стандартный, хорошо заданный язык, то вы можете найти его в Интернете, но если это внутренняя вещь, вам может понадобиться написать свой собственный (возможно, используя генератор синтаксического анализатора, такой как ANTLR.)

Пакет javax.script содержит некоторые инструменты для интеграции внешних скриптовых движков, таких как Javascript-интерпретатор. Альтернативная идея заключалась бы в создании механизма сценариев и подачи выражений на это.

Ответ 3

Вы в основном оцениваете сценарий выражения. В зависимости от того, что разрешено в этом выражении, вы можете уйти с чем-то очень простым (регулярное выражение, идентифицирующее группы) или очень сложным (встроить механизм javascript?).

Я предполагаю, что вы смотрите на простой случай, где выражение: [border0] [оператор] "значение" [оператор] [граница1]

Если одна, но не обе группы [границы] [оператора], могут быть опущены. (И если оба являются подарками, оператор должен быть таким же)

Я бы использовал регулярное выражение для группы захвата.

Что-то вроде: (?: (\ d +)\s * ([< > ])\s *)? value (?:\s * ([< > ])\s * (\ d +))

И затем: граница 1 = группа (1); operator1 = группа (2); operator2 = группа (3); border2 = группа (4)

Ответ 4

Последняя версия java (Java 7) позволяет операторам операторов switch в Strings, если не так много возможных вариантов, вы можете просто сделать это или подобное:

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

Ответ 5

Вы должны попробовать разбор строки внутри оператора if, выполнив что-то вроде

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

В parseMyString можно определить, что вам нужно оценить для условия. Если вы не знаете, как создать парсер, посмотрите на: http://www.javapractices.com/topic/TopicAction.do?Id=87

Ответ 6

Для оценки условий с максимальной гибкостью используйте язык сценариев, предназначенный для встраивания, например MVEL может анализировать и оценивать простые условные выражения, такие как те в вопросе.

Использование MVEL имеет огромное преимущество перед использованием механизма Scripting в Java 1.6+ (в частности, с JavaScript): с MVEL вы можете скомпилировать скрипты для байт-кода, делая их оценку намного более эффективной во время выполнения.

Ответ 7

Это не отвечает на ваш вопрос как таковой; он предлагает альтернативное решение, которое может повлиять на тот же результат.

Вместо хранения одного столбца базы данных с псевдокодом, который определяет условие, создайте таблицу, в которой схема определяет типы условий, которые должны быть удовлетворены, и значения этих условий. Это упрощает программную оценку этих условий, но может усложниться, если у вас есть множество типов условий для оценки.

Например, у вас может быть таблица, которая выглядит следующим образом.

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

Эти записи строк, соответственно, соответствуют правилам value > 2 и 6 > value > 4.

Это дает ряд преимуществ в отношении предлагаемого вами подхода.

  • Повышение производительности и чистоты
  • Ваши условия могут быть оценены на уровне базы данных и могут использоваться для фильтрации запросов
  • Вам не нужно беспокоиться о том, как обрабатывать сценарии, в которых нарушен синтаксис псевдокода

Ответ 8

Очень хороший способ сделать это, помимо использования 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, и она вернет подходящее перечисление, которое помещается в блок case switch для выполнения условной операции. В приведенном выше коде вы можете передать любую строку вместо того, что было передано в этом примере