Valuta la stringa come condizione Java

Devo recuperare un set di valori di colonna da D / B e controllarlo come condizione.

Ad esempio, avrò stringhe come "value > 2" , "4 < value < 6" in una colonna D / B. (il valore è quello che viene confrontato di volta in volta). Avrò un valore variabile dichiarato nel mio codice e dovrei valutare questa condizione.

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

Come posso fare questo?? Qualsiasi aiuto è apprezzato. Grazie.

Ecco un esempio che utilizza la libreria di scripting standard (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 } } 

Stai sostanzialmente valutando un’espressione scritta. A seconda di ciò che è permesso in quell’espressione, puoi farla franca con qualcosa di molto semplice (espressione regolare che identifica i gruppi) o molto complessa (incorpora un motore javascript?).

Presumo che tu stia osservando il caso semplice, in cui l’espressione è: [boundary0] [operator] “value” [operator] [boundary1]

Dove uno, ma non entrambi i gruppi [limite] [operatore] potrebbero essere omessi. (E se entrambi sono regali, l’operatore dovrebbe essere lo stesso)

Vorrei usare un’espressione regolare per questo con i gruppi di cattura.

Qualcosa come: (?: (\ D +) \ s * ([<>]) \ s *)? Value (?: \ S * ([<>]) \ s * (\ d +))?

E poi: boundary1 = group (1); operator1 = group (2); operator2 = group (3); boundary2 = group (4)

Non sarà banale: hai bisogno di un parser per il linguaggio delle espressioni usato nel tuo database. Se si tratta di un linguaggio standard e ben specificato, potrebbe essere ansible trovarne uno su Internet, ma se si tratta di una cosa interna, potrebbe essere necessario scrivere il proprio (magari usando un generatore di parser come ANTLR).

Il pacchetto javax.script contiene alcuni strumenti per l’integrazione di motori di scripting esterni come un interprete Javascript. Un’idea alternativa sarebbe quella di introdurre un motore di scripting e alimentare le espressioni a tale scopo.

Dovresti provare ad analizzare la stringa all’interno dell’istruzione if facendo qualcosa di simile

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

In parseMyString è ansible determinare ciò che è necessario valutare per la condizione. Se non sai come creare un parser, dai un’occhiata a: http://www.javapractices.com/topic/TopicAction.do?Id=87

Questo non risponde alla tua domanda di per sé; offre una soluzione alternativa che può avere lo stesso risultato.

Invece di memorizzare una singola colonna di database con pseudocode che definisce una condizione, creare una tabella in cui lo schema definisca i tipi di condizioni che devono essere soddisfatte e i valori di tali condizioni. Questo semplifica la valutazione programmatica di tali condizioni, ma può diventare complicato se si dispone di una varietà di tipi di condizioni da valutare.

Ad esempio, potresti avere una tabella simile alla seguente.

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

Quelle voci di riga, rispettivamente, corrispondono al value > 2 regole value > 2 e 6 > value > 4 .

Ciò conferisce una serie di vantaggi rispetto all’approccio fornito.

  • Miglioramento delle prestazioni e pulizia
  • Le condizioni possono essere valutate a livello di database e possono essere utilizzate per filtrare le query
  • Non devi preoccuparti di gestire gli scenari in cui la syntax dello pseudocode è interrotta

L’ultima versione di java (Java 7) consente di impostare Switch Case su Stringhe, se non ci sono molte varianti possibili è ansible farlo solo o simile:

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

Per valutare le condizioni con la massima flessibilità, utilizzare un linguaggio di scripting progettato per l’incorporamento, ad esempio MVEL può analizzare e valutare espressioni condizionali semplici come quelle della domanda.

L’utilizzo di MVEL ha un enorme vantaggio rispetto all’utilizzo del motore di scripting in Java 1.6+ (in particolare, con JavaScript): con MVEL è ansible compilare gli script in bytecode, rendendo la loro valutazione molto più efficiente in fase di runtime.

Un ottimo modo per farlo a parte l’utilizzo di Java 7 sta usando enumerazioni. Dichiarare enum come mostrato di seguito

L’enumerazione precedente ha una collezione di costanti i cui valori sono impostati sulle stringhe che ci si aspetta vengano restituiti dal database. Poiché è ansible utilizzare le enumerazioni nei casi di switch, il codice rimanente diventa facile

 enum MyEnum { val1("value < 4"),val2("4 2){} break; case val2: if(4 < value && value < 6) {} break; default: } } public static void main(String[] args) { String str = "4 

Tutto quello che devi fare è passare la tua stringa al metodo enum.valueof e restituirà l'enfasi appropriata che viene inserita in un blocco di switch switch per eseguire un'operazione condizionale. Nel codice precedente è ansible passare qualsiasi stringa al posto di ciò che viene passato in questo esempio