3

供以后参考:

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>来存储运算符(字符串)和应该调用的方法。基本上,在当前类的构造函数中,我输入:

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

我想这只是一种冗长的询问是否有办法分配调用方法的返回值?就像是:

result = getMethodFromKey(ops, operator).invoke(o, numOne, numTwo); //This doesn't work :(

任何帮助表示赞赏。此外,如果我的方法完全错误,我会很感激朝着正确的方向前进。


免责声明:我在 Java 方面相对缺乏经验,并且以过于复杂的事情而闻名,所以请指出我设计中的任何严重缺陷。:)

4

3 回答 3

1

如果invoke()返回一个Object你知道是 a 的double,你可以像这样转换它:

result = (Double) getMethodFromKey(ops, operator).invoke(o, numOne, numTwo); 

由于doubleis 是一个原始类型,它不是 type Object,因此您需要将其强制转换为 a Double,并通过拆箱得到 a double

于 2013-08-02T01:09:13.567 回答
1

如果您确定所有操作都将在一个类上(没有可扩展性),那么您应该考虑使用 anenum来代替。您可以在 中添加一个实例字段enum表示与操作对应的字符命令,然后有一个由每个值evaluate实现的抽象方法。enum

于 2013-08-02T01:16:08.517 回答
1

invoke()返回Object,并且由于 Java 不知道如何将 an 分配Object给 adouble这不会编译。invoke首先将doublefrom 方法装箱到Double. 您现在必须将其从Objectto 转换为Double(然后可以调用.doubleValue(),但这是自动完成的)才能使其正常工作。

我 [...] 以过于复杂的事情而闻名,所以请指出我设计中的任何严重缺陷。:)

使用反射而不是接口。AMethod是一个函数对象。但它不是类型安全的使用。一个接口可以做同样的事情而没有这些问题。

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

铸造的需要已经消失了。

于 2013-08-02T01:40:21.877 回答