是否可以将算术运算符传递给java中的方法?

时间:2010-05-25 06:23:17

标签: java operators math

现在我将不得不编写一个如下所示的方法:

public String Calculate(String operator, double operand1, double operand2)
{

        if (operator.equals("+"))
        {
            return String.valueOf(operand1 + operand2);
        }
        else if (operator.equals("-"))
        {
            return String.valueOf(operand1 - operand2);
        }
        else if (operator.equals("*"))
        {
            return String.valueOf(operand1 * operand2);
        }
        else
        {
            return "error...";
        }
}

如果我能编写更像这样的代码,那将是很好的:

public String Calculate(String Operator, Double Operand1, Double Operand2)
{
       return String.valueOf(Operand1 Operator Operand2);
}

所以运算符会替换算术运算符(+, - ,*,/...)

有人知道这样的东西是否可以用于java?

9 个答案:

答案 0 :(得分:36)

不,你不能用Java做到这一点。编译器需要知道运算符正在做什么。您可以做的是枚举:

public enum Operator
{
    ADDITION("+") {
        @Override public double apply(double x1, double x2) {
            return x1 + x2;
        }
    },
    SUBTRACTION("-") {
        @Override public double apply(double x1, double x2) {
            return x1 - x2;
        }
    };
    // You'd include other operators too...

    private final String text;

    private Operator(String text) {
        this.text = text;
    }

    // Yes, enums *can* have abstract methods. This code compiles...
    public abstract double apply(double x1, double x2);

    @Override public String toString() {
        return text;
    }
}

然后您可以编写如下方法:

public String calculate(Operator op, double x1, double x2)
{
    return String.valueOf(op.apply(x1, x2));
}

并称之为:

String foo = calculate(Operator.ADDITION, 3.5, 2);
// Or just
String bar = String.valueOf(Operator.ADDITION.apply(3.5, 2));

答案 1 :(得分:9)

Java中的方法参数必须是表达式。运算符本身不是表达式。这在Java中是不可能的。

当然,您可以传递代表这些运算符的对象(可能是enum常量),并相应地执行操作,但您不能将运算符本身作为参数传递。


其他提示

由于您刚刚开始使用Java,因此最好尽早掌握这些信息,以便于您的未来发展。

  • 方法名称以小写字母开头:calculate而不是Calculate
  • 变量名称以小写字母开头:operator而不是Operator
  • Double是一种引用类型,即原始类型double的框。
    • Effective Java 2nd Edition,Item 49:首选原始类型为盒装基元
  • 不要return "error..."。相反,throw new IllegalArgumentException("Invalid operator");

另见

答案 2 :(得分:4)

使用回调接口只有繁琐的方法。像

这样的东西
interface Operator {
    public Double do(Double x, Double y);
}

然后实现所需的运算符:

Operator plus = new Operator() {
    public Double do(Double x, Double y) {
        return x + y;
    }
};

你的泛型方法接受一个运算符和两个参数:

public String Calculate(Operator operator, Double x, Double y) {
    return String.valueOf( operator.do(x, y) );
}

如果您只需要较小的固定数量的运算符,也可以使用枚举而不是接口。

答案 3 :(得分:3)

您无法直接传递运算符。您可以使用functors

public double Calculate(BinaryFunction<Double, Double, Double> op, double Operand1, double Operand2)
{
  return (double)op.evaluate(Operand1, Operand2);
}

答案 4 :(得分:2)

你可以

  1. 使用JVM的函数语言来实现代码的这部分(clojure,scala et el),围绕数学运算符包装lambda函数并将这些函数作为参数传递

  2. 获取像http://www.singularsys.com/jep/这样的Java表达式评估程序(并且必须有许多免费替代方案)

答案 5 :(得分:1)

这样做是不可能的。

你需要一个解析器来做你想做的事情,这可能很麻烦。

你可能会问错误的问题,因为你的答案是错误的。

如果您正在寻找数学解析器,您可能需要在SF上查看此项目:http://sourceforge.net/projects/jep/

这可能有一些答案。

答案 6 :(得分:1)

这会很好,不是吗?但是,你不能这样做。你可以通过编写自己的“操作符”来完成类似的事情。

public interface Operator {
  Double calculate(Double op1, Double op2);
}

public Addition implements Operator {
  @Override
  Double calculate(Double op1, Double op2) { return op1 + op2; }
}

public class Calculator {
  private static Operator ADDITION = new Addition();
  private static Map<String,Operator> OPERATORS = new HashMap<String,Operator>();
  static {
    OPERATORS.put("+",ADDITION);
  }

  public String Calculate(String operator, Double operand1, Double operand2) {
    return String.valueOf(OPERATORS.get(operator).calculate(operand1,operand2);
  }
}

您可以了解如何将其扩展到许多其他运营商......而且不仅仅是双打明显。我的方法的优点是你可以保持你的方法签名接受 String 运算符。

答案 7 :(得分:0)

自从在 Java 8 中引入 lambda expressionsfunctional interfaces 后,您可以更习惯地进行操作。

public static <T> T calculate(BinaryOperator<T> operator, T operand1, T operand2) {
  return operator.apply(operand1, operand2);
}

您是否希望将这些 BinaryOperator 预定义(或在某处声明为常量)更多的是一种风格选择。

Integer r1 = calculate((a, b) -> a + b, 2, 2); // 4
Integer r2 = calculate(Integer::sum, 2, 2); // 4

答案 8 :(得分:-3)

操作员AFAIK不能作为任何语言的参数传递(至少我遇到过)。

原因是只有值(通过复制或引用)可以作为“值传递给参数”。

运算符代表没有值。