所以我必须编写一个程序,从用户那里获取公式并计算它们。
Age, Height, fights, (age+height)*fights <- user defined
10, 5, 10, 150 <- I calculate this
1, 2, 1, 3 <- I calculate this
但现在让我说我改变了周围的值,我希望公式列能够动态更新吗?无论如何要做到这一点?我将每行存储到一个数组列表中,该列表是数组列表的数组列表。任何建议或指导都会非常有用,谢谢:)
答案 0 :(得分:0)
您可能希望使用多个表达式计算引擎中的一个而不是ArrayLists。您可以查看Expr4J或BIRT以获取可能的解决方案。
答案 1 :(得分:0)
您可能希望为这些数组编写事件侦听器。文档可以在这里找到 http://download.oracle.com/javase/tutorial/uiswing/events/listdatalistener.html
更简单的解决方案是编写一个计算公式的简单方法,并从程序的每个部分调用它来触发列表值的更改(但此解决方案可能会使代码混乱)。如果这是一个家庭作业或非常小的项目你可以采用这种方法,否则我建议写一个听众。
答案 2 :(得分:0)
我们可以修改它以制作一个简单的引擎
public interface Function<T> {
T operate(Map<String,T> values);
}
public class Calculation<T> {
private Map<String,T> values;
private Function<T> function;
public Calculation(Map<String,T> values, Function<T> function) {
this.values = new HashMap<String,T>(values);
this.function = function;
}
public T calculate() {
return function.operate(Collections.unmodifiableMap(values));
}
// assume setters and getters are in place to manipulate the backing map and the functor object
}
有了这个,我们可以定义各种功能和计算
public static void main(String[] args) {
Function<Integer> original = new Function<Integer>() {
public Integer operate(Map<String,Integer> values) {
// these will throw exceptions if they don't exist, which is desired
// granted it's NullPointerException instead of IllegalStateException, but close enough for this example
int age = values.get("age").intValue();
int height = values.get("height").intValue();
int fights = values.get("fights").intValue();
return (age+height)*fights;
}
};
Map<String,Integer> map = new Map<String,Integer>();
map.put("age",10);
map.put("height",100);
map.put("fights",25);
Calculation<Integer> calc = new Calculation<Integer>(map,original);
// later someone can replace either the values in the backing map
// or replace the function altogether to get a new function
}
当您尝试使其不仅是用户定义但用户输入时,问题就出现了。用户可以将该功能定义为您预先输入的一组功能之一。在这种情况下,您需要有一个解析器,如下所示:
value + (other + (something * that)) / wazook
进入这个:
EquationBuilder<Integer> eb = new EquationBuilder<Integer>();
eb.append(map.get("value"));
eb.append(OPERATOR.PLUS);
// etc
return eb.evaluate();
但这可能超出了你的任务范围。或许它不是。
希望这比我之前的例子更接近你的要求。
答案 3 :(得分:0)
说实话我会用更多的OO方式,请看一下:
public class Parameter {
private String id;
private Number value;
public Parameter(String id, Number value) {
this.id = id;
this.value = value;
}
public String getId() {
return id;
}
public Number getValue() {
return value;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Parameter) {
Parameter parameter = (Parameter) obj;
return id.equals(parameter.getId());
}
return super.equals(obj);
}
}
public class Equation {
private String formula;
private Set<Parameter> parameters;
public Equation(String formula, Parameter ... parameters) {
this.formula = formula;
this.parameters = new HashSet<Parameter>();
for(Parameter parameter : parameters) {
this.parameters.add(parameter);
}
validatePresenceOfAllParameters();
}
private void validatePresenceOfAllParameters() {
// here you parse formula and check if all parameters are present
}
public Number doTheMagic() {
Number result = null;
// here you do the all magic related to equation and its parameters
return result;
}
// public void setParameter(Parameter parameter) {
// parameters.add(parameter);
// validatePresenceOfAllParameters();
// }
}
我也会让Parameter
和Equation
对象成为不可变的,如果有必要改变我会制作另一个方程式对象但是如果这是要求你可以在{{1}中编写方法}添加/设置Equation
的。如果Parameter
具有相同的ID,Set
将正确处理它们。