2012-06-06 2 views
18

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

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

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

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

+1

Это звучит довольно болезненно – NimChimpsky

+0

Я рекомендую найти лучший способ сделать это, иначе это нужно сделать, используя Reflection. – Jivings

+0

Да, неправильно ... удаленный пост – dardo

ответ

30

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

Я занимаюсь java годами, а не через месяц, когда я Посмотрите, что-то новое. Я не уверен, хорошо это или плохо. – NimChimpsky

+0

Он бросает исключение NullPointerException на LOC: engine.eval ("value = 10"); Какая может быть возможная причина? –

+0

@VenkateshwarraoSurabhi Я не получаю эту ошибку - это, вероятно, означает, что 'engine' равно null. Вы используете Java 1.6+? Нет опечаток в названии двигателя: «JavaScript» с верхним регистром J и S? – assylias

1

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

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

+0

Спасибо за ввод. Да, будут оцениваться только эти типы выражений. –

1

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

Я предполагаю, что вы смотрите на простом случае, когда выражение является: [boundary0] [оператор] «значение» [оператор] [boundary1]

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

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

Что-то вроде: (?: (\ D +) \ s * ([<>]) \ s *)? Значение (?: \ S * ([<>]) \ s * (\ d +))?

И затем: border1 = группа (1); operator1 = группа (2); operator2 = группа (3); boundary2 = группа (4)

+0

Функциональный пример «условий синтаксического анализа в java с использованием regex» можно найти здесь: https://stackoverflow.com/a/45730477/1833961 – bvdb

0

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

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(); 
} 
0

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

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

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

0

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

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

0

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

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

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

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

Эти данные строки, соответственно карту с правилами value > 2 и .

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

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

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

+1

Я думаю, что голова дяди Боба Мартина просто взорвалась. –

+0

Некоторая обратная связь, если приветствуется: поскольку OP говорит о том, чтобы вытаскивать строки из базы данных, ваш метод использует много кода и недостаточно динамичен/достаточно гибким. Если вы не уверены в возможном решении, вам лучше не предлагать это, так как люди будут отклонять ваш ответ. Однако, если вы узнаете из этого вопроса, не стесняйтесь отвечать на подобные вопросы или делиться знаниями. ;-) – siebz0r

+0

hmm ok Я пропустил точку этих строк, исходящих из db. Дело здесь состояло в том, чтобы показать мощь перечислений на Java и как его можно использовать. Извините, ребята – prashant

Смежные вопросы