供以后参考:
Operations o = new Operations(); //class containing the operation methods
HashMap<String, Method> ops = new HashMap<String, Method>();
我正在开发一个程序,它将通过控制台解析数学表达式输入,或者最终可能是GUI。
目前,我有一个名为“Operations”的类,它有各种基本的数学函数(稍后将添加更多,现在只测试)。在另一个类中,我有一个方法,通过获取操作数,连续运算符和另一个操作数来计算结果,并调用一个方法来计算表达式。它将计算所需的信息存储在:
double numOne = //...
char operator = //...
double numTwo = //...
double result = //...
现在我不希望发表长switch
/ case
声明或if
声明:
if (operator.equals("+")) //I know .equals() doesn't use chars; it's an example
o.add(numOne, numTwo);
else if (operator.equals("-"))
o.subtract(numOne, numTwo);
每次操作都会打开。这就是为什么我尝试创建一个HashMap<String, Method>
来存储运算符(String)和应该调用的方法。基本上,在当前类的构造函数中,我把:
ops.put("+", o.getClass().getMethod("add", double.class, double.class));
ops.put("-", o.getClass().getMethod("subtract", double.class, double.class));
//etc. Which in and of itself is also pretty lengthy
现在,一旦通过运算符识别方法,我需要另一种方法来返回Method
来调用。
private Method getMethodFromKey(HashMap<String, Method> map, char op) {
Method method = null;
for (Map.Entry<String, Method> e: map.entrySet()) {
if (e.getKey().equals(op))
method = e.getValue();
}
return method;
}
最后,一旦我有正确的方法,我可以用:
来调用它getMethodFromKey(ops, operator).invoke(o, numOne, numTwo);
一切都很好。我的问题是,我/将要调用的方法是getter方法;他们返回双倍。例如:
public double add(double one, double two) {
double answer = 0;
answer = one + two;
return answer;
}
我想这只是一个冗长的问题,是否有办法分配一个innvoked方法的返回值?类似的东西:
result = getMethodFromKey(ops, operator).invoke(o, numOne, numTwo); //This doesn't work :(
感谢任何帮助。另外,如果我的方法完全错误,我会欣赏正确的方向。
免责声明:我对Java相对缺乏经验并因过于复杂的事情而闻名,所以请指出我的设计中存在的任何严重缺陷。 :)
答案 0 :(得分:1)
如果invoke()
返回Object
您知道的double
,则可以这样投出:
result = (Double) getMethodFromKey(ops, operator).invoke(o, numOne, numTwo);
由于double
是基元,而不是Object
类型,因此您需要将其转换为Double
,并通过unboxing,我们得到double
1}}。
答案 1 :(得分:1)
如果您确定所有操作都将在一个类上(无可扩展性),那么您应该考虑使用enum
。您可以add an instance field到enum
来表示与操作对应的字符命令,然后使用由evaluate
值实现的抽象enum
方法。
答案 2 :(得分:1)
invoke()
返回Object
,由于Java不知道如何将Object
分配给double
,因此无法编译。 invoke
首先将方法中的double
装入Double
。您现在必须从Object
转换为Double
(然后可以调用.doubleValue()
,但这会自动完成)以使其生效。
我因为过于复杂的事情而闻名,所以请指出我的设计中存在的任何严重缺陷。 :)
使用反射而不是界面。 Method
是一个函数对象。但它使用起来并不安全。没有这些问题,接口也可以这样做。
interface Operation {
double evaluate(double a, double b);
}
然后在地图中放置实现接口的对象:
ops.put("+", new Operation() {
public double evaluate(double a, double b) {
return a+b;
});
你可以做到
double result = getMethodFromKey(ops, operator).evaluate(numOne, numTwo);
投射的需要消失了。