2012-06-06 13 views
18

Muszę pobrać zestaw wartości kolumn z D/B i sprawdzić go jako warunek.Oceń ciąg jako warunek Java

Na przykład będę mieć ciągi takie jak "value > 2", "4 < value < 6" w kolumnie D/B. (wartość jest tą, która jest porównywana przez cały czas). Będę mieć wartość zmiennej zadeklarowaną w moim kodzie i powinienem ocenić ten warunek.

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

Jak mogę to zrobić? Każda pomoc jest muceh doceniona. Dzięki.

+1

To brzmi raczej bolesnie – NimChimpsky

+0

Polecam znalezienie lepszego sposobu na zrobienie tego, w przeciwnym razie będzie to musiało zostać wykonane za pomocą Odbicia. – Jivings

+0

Tak, błędnie przeczytany ... usunięty wpis – dardo

Odpowiedz

30

Oto przykład przy użyciu standardu (Java 1.6 +) biblioteka skryptów:

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

Robię java od lat, a nie miesiąc mija, kiedy ja wykładam patrz, ucz się czegoś nowego. Nie jestem pewien, czy to dobrze, czy źle. – NimChimpsky

+0

Rzuca wyjątek NullPointerException na LOC: engine.eval ("value = 10"); Jaki może być możliwy powód? –

+0

@VenkateshwarraoSurabhi Nie otrzymuję tego błędu - prawdopodobnie oznacza to, że 'engine' ma wartość null. Czy używasz Java 1.6+? Brak literówki w nazwie silnika: "JavaScript" z dużymi literami J i S? – assylias

1

To nie będzie trywialne: potrzebujesz parsera dla języka wyrażenia używanego w bazie danych. Jeśli jest to jakiś standardowy, dobrze określony język, możesz go znaleźć w Internecie, ale jeśli jest to sprawa wewnętrzna, może będziesz musiał napisać własną (np. Przy użyciu generatora analizatora składni, takiego jak ANTLR.)

Pakiet javax.script zawiera narzędzia do integracji zewnętrznych silników skryptów, takich jak interpreter JavaScript. Alternatywnym pomysłem byłoby wprowadzenie silnika skryptów i dodanie do niego wyrażeń.

+0

Dzięki za dane wejściowe. Tak, oceniane będą tylko te typy wyrażeń. –

1

Zasadniczo oceniasz wyrażenie skryptowe. W zależności od tego, co jest dozwolone w tym wyrażeniu, możesz uciec z czymś bardzo prostym (wyrażenie regularne identyfikujące grupy) lub bardzo skomplikowanym (osadzić silnik javascript?).

Jestem zakładając, że jesteś patrząc na prostym przypadku, gdy wyrażenie jest: [boundary0] [operator] "wartość" [operator] [boundary1]

Gdzie jeden, ale nie obie [borderary] Grupy [operator] mogą zostać pominięte. (A jeśli oba są prezentami, operator powinien być taki sam)

Używałbym do tego wyrażenia regularnego z funkcją przechwytywania grup.

Coś jak: (?: (\ D +) \ s * ([<>]) \ s *)? Wartość (?: \ S * ([<>]) \ s * (\ d +))?

A następnie: granica1 = grupa (1); operator1 = grupa (2); operator2 = grupa (3); boundary2 = grupa (4)

+0

Funkcjonalny przykład "warunków parsowania w java za pomocą wyrażeń regularnych", można znaleźć tutaj: https://stackoverflow.com/a/45730477/1833961 – bvdb

0

Najnowsza wersja Java (Java 7) umożliwia switch przypadku na smyczki, jeśli nie ma wielu możliwych wariantów może po prostu ten lub podobny zrobić:

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

Dla oceny warunków z maksymalną elastyczność wykorzystuje język skryptowy przeznaczony do osadzania, na przykład MVEL może analizować i oceniać proste wyrażenie warunkowe, takie jak te w pytaniu.

Korzystanie z MVEL ma jedną ogromną zaletę w porównaniu z używaniem silnika Skrypty w Javie 1.6+ (w szczególności z JavaScriptem): dzięki MVEL możesz kompilować skrypty do kodu bajtowego, dzięki czemu ich ocena jest znacznie wydajniejsza w środowisku wykonawczym.

0

To nie odpowiada na twoje pytanie jako takie; oferuje alternatywne rozwiązanie, które może mieć taki sam efekt.

Zamiast przechowywać pojedynczą kolumnę bazy danych z pseudokodami, które definiują warunek, należy utworzyć tabelę, w której schemat definiuje typy warunków, które muszą być spełnione, oraz wartości tych warunków. Upraszcza to programową ocenę tych warunków, ale może się skomplikować, jeśli masz do wyboru wiele różnych warunków.

Na przykład może istnieć tabela wyglądająca następująco.

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

Te wpisy rzędu, odpowiednio map z zasadami value > 2 i .

Zapewnia to szereg korzyści w stosunku do podejścia, które oferujesz.

  • Poprawiona wydajność i czystość
  • Twoje warunki mogą być oceniane na poziomie bazy danych i mogą być używane do filtrowania zapytań
  • Nie musisz martwić się o obsługę scenariuszy, w których składnia pseudokod jest uszkodzony
-3

Bardzo dobrym sposobem na to, oprócz używania Java 7, jest używanie wyliczeń. Deklaracja wyliczenia zgodnie z poniższym opisem:

Powyższe wyliczenie zawiera kolekcję stałych, których wartości są ustawione na ciągi, których oczekiwanie zostanie zwrócone z bazy danych. Jak można używać stałe teksty w przypadkach przełączyć pozostały kod staje się łatwe

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

Wszystko co musisz zrobić, to przekazać swój ciąg metody enum.valueof i zwróci jest właściwa enum, który znalazł się w sytuacji przełącznik bloku wykonać operację warunkową. W powyższym kodzie możesz przekazać dowolny ciąg znaków w miejsce tego, co jest przekazywane w tym przykładzie:

+1

Myślę, że głowa wuja Boba Martina właśnie eksplodowała. –

+0

Niektóre opinie, jeśli z zadowoleniem: W OP opowiada o ciągnięciu ciągi z bazy danych, Twoja metoda używa dużo kodu i nie jest wystarczająco dynamiczne/elastyczne. Jeśli nie masz pewności co do możliwego rozwiązania, lepiej nie sugeruj tego, ponieważ ludzie nie zgodzą się na twoją odpowiedź. Jeśli jednak nauczysz się od tego pytania, możesz odpowiedzieć na podobne pytania lub podzielić się wiedzą. ;-) – siebz0r

+0

hmm ok Brakowało mi punktów tych strun pochodzących z bazy danych. Chodziło o to, aby pokazać moc wyrażeń w Javie i sposób jej wykorzystania. Przepraszam, chłopaki, bardzo źle – prashant