Поскольку есть много ответов, я добавляю свою реализацию поверх метода eval()
с некоторыми дополнительными функциями, такими как поддержка факториала, оценка сложных выражений и т. д.
package evaluation;
import java.math.BigInteger;
import java.util.EmptyStackException;
import java.util.Scanner;
import java.util.Stack;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class EvalPlus {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("This Evaluation is based on BODMAS rule\n");
evaluate();
}
private static void evaluate() {
StringBuilder finalStr = new StringBuilder();
System.out.println("Enter an expression to evaluate:");
String expr = scanner.nextLine();
if(isProperExpression(expr)) {
expr = replaceBefore(expr);
char[] temp = expr.toCharArray();
String operators = "(+-*/%)";
for(int i = 0; i < temp.length; i++) {
if((i == 0 && temp[i] != '*') || (i == temp.length-1 && temp[i] != '*' && temp[i] != '!')) {
finalStr.append(temp[i]);
} else if((i > 0 && i < temp.length -1) || (i==temp.length-1 && temp[i] == '!')) {
if(temp[i] == '!') {
StringBuilder str = new StringBuilder();
for(int k = i-1; k >= 0; k--) {
if(Character.isDigit(temp[k])) {
str.insert(0, temp[k] );
} else {
break;
}
}
Long prev = Long.valueOf(str.toString());
BigInteger val = new BigInteger("1");
for(Long j = prev; j > 1; j--) {
val = val.multiply(BigInteger.valueOf(j));
}
finalStr.setLength(finalStr.length() - str.length());
finalStr.append("(" + val + ")");
if(temp.length > i+1) {
char next = temp[i+1];
if(operators.indexOf(next) == -1) {
finalStr.append("*");
}
}
} else {
finalStr.append(temp[i]);
}
}
}
expr = finalStr.toString();
if(expr != null && !expr.isEmpty()) {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try {
System.out.println("Result: " + engine.eval(expr));
evaluate();
} catch (ScriptException e) {
System.out.println(e.getMessage());
}
} else {
System.out.println("Please give an expression");
evaluate();
}
} else {
System.out.println("Not a valid expression");
evaluate();
}
}
private static String replaceBefore(String expr) {
expr = expr.replace("(", "*(");
expr = expr.replace("+*", "+").replace("-*", "-").replace("**", "*").replace("/*", "/").replace("%*", "%");
return expr;
}
private static boolean isProperExpression(String expr) {
expr = expr.replaceAll("[^()]", "");
char[] arr = expr.toCharArray();
Stack stack = new Stack();
int i =0;
while(i < arr.length) {
try {
if(arr[i] == '(') {
stack.push(arr[i]);
} else {
stack.pop();
}
} catch (EmptyStackException e) {
stack.push(arr[i]);
}
i++;
}
return stack.isEmpty();
}
}
. gist в любое время здесь . Также прокомментируйте, есть ли какие-либо проблемы. Спасибо.
Я не полагаю, что это возможно из-за стирания. Мы обычно переключались на подынтерфейсы со строгим контролем типов при движении для полного автопроводного соединения:
public interface LongService extends ISimpleService<Long> {}
public interface StringService extends ISimpleService<String> {}
После выполнения этого переключателя мы нашли, что нам на самом деле понравилось это вполне прилично, потому что это позволяет нам делать, "находят использование" отслеживанием намного лучше, что-то, что Вы освобождаете с интерфейсами дженериков.
я не думаю, что это возможно без Спецификатора
плохая попытка показать мои Решения с genericDAO, извините, если это немного детализировано
Определение
public interface GenericDAO<T, ID extends Serializable> (...)
public class GenericDAOImpl<T, ID extends Serializable>
implements GenericDAO<T, ID>
(...) important is this constructor
public GenericDAOImpl(Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
Интерфейсного и Класса реализации пружинное бобовое определение, заметьте, что краткий обзор = "верный"
<bean id="genericHibernateDAO" class="de.optimum24.av.pers.ext.hibernate.dao.GenericDAOImpl"
abstract="true">
<description>
<![CDATA[
Definition des GenericDAO.
]]>
</description>
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Используя этот genericDAO без специального класса реализации
<bean id="testHibernateChildDao" class="de.optimum24.av.pers.ext.hibernate.dao.GenericDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
<constructor-arg>
<value>de.optimum24.av.pers.test.hibernate.domain.TOChild</value>
</constructor-arg>
</bean>
замечает аргумент конструктора с реальным классом, если Вы работаете с Аннотацией Spring, необходимо сделать:
@Autowired
@Qualifier(value = "testHibernateChildDao")
private GenericDAO<TOChild, Integer> ToChildDAO;
для различения различных версий genericDao Бобов (замечают Спецификатор с прямой ссылкой к Beanname)
Используя этот genericDAO со специальным классом реализации
Интерфейс и Класс
public interface TestHibernateParentDAO extends GenericDAO<TOParent, Integer>{
void foo();
}
public class TestHibernateParentDAOImpl extends GenericDAOImpl<TOParent, Integer>
implements TestHibernateParentDAO {
@Override
public void foo() {
//* no-op */
}
}
Бобовое Определение заметьте "родительскую" Ссылку на краткий обзор genericDAO выше
<bean id="testHibernateParentDao" class="de.optimum24.av.pers.test.hibernate.dao.TestHibernateParentDAOImpl"
parent="genericHibernateDAO" />
и использование с Аннотацией Spring
@Autowired
private TestHibernateParentDAO ToParentDAO;