¿Es posible pasar operadores aritméticos a un método en Java?

En este momento voy a tener que escribir un método que se ve así:

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

Sería bueno si pudiera escribir el código más como este:

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

Entonces, el operador reemplazaría a los operadores aritméticos (+, -, *, / …)

¿Alguien sabe si algo como esto es posible en Java?

No, no puedes hacer eso en Java. El comstackdor necesita saber qué está haciendo su operador. Lo que podrías hacer en cambio es una enumeración:

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

A continuación, puede escribir un método como este:

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

Y llámalo así:

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

Los argumentos del método en Java deben ser expresiones. Un operador en sí mismo no es una expresión. Esto no es posible en Java.

Por supuesto, puede pasar objetos (tal vez constantes enum ) que representen a esos operadores, y actuar en consecuencia, pero no puede pasar los mismos operadores como parámetros.


Consejos adicionales

Como recién está iniciando Java, es mejor incorporar estas informaciones desde el principio para facilitar su desarrollo futuro.

  • Los nombres de los métodos comienzan con minúsculas: calculate lugar de Calculate
  • Los nombres de las variables comienzan con minúsculas: operator lugar de Operator
  • Double es un tipo de referencia, el cuadro para el tipo primitivo double .
    • Effective Java 2nd Edition, Item 49: Prefiere los tipos primitivos a las primitivas en caja
  • No return "error..." . En cambio, throw new IllegalArgumentException("Invalid operator");

Ver también

  • Guía de lenguaje Java / Autoboxing
  • Lecciones / Excepciones de Java
  • Convenciones de encoding / Nomenclatura
    • Desgraciado error en este documento: ¿Cómo tiene sentido esta afirmación? (Convención de nomenclatura de Sun para variables de Java)

No puede pasar operadores directamente. Puedes usar funtores .

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

Solo existe la forma engorrosa de hacerlo con una interfaz de callback. Algo como

 interface Operator { public Double do(Double x, Double y); } 

Luego implementa los operadores que necesita:

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

Y su método genérico toma un operador y los dos argumentos:

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

También puede usar una enumeración en lugar de una interfaz si solo necesita un número más pequeño y fijo de operadores.

Tu también puedes

  1. Use un lenguaje funcional para que JVM implemente esta parte de su código (clojure, scala et el), envuelva las funciones lambda alrededor de los operadores matemáticos y pase esas funciones como parámetros

  2. Obtenga un evaluador de expresiones para Java como http://www.singularsys.com/jep/ (y también debe haber muchas alternativas gratuitas)

No, esto no es posible de esta manera.

Necesitará un analizador para hacer lo que quiera, y esto puede ser engorroso.

Probablemente estés haciendo una pregunta incorrecta, ya que recibes la respuesta incorrecta.

Si está buscando un analizador matemático, le recomendamos echar un vistazo a este proyecto en SF: http://sourceforge.net/projects/jep/

Puede haber algunas respuestas en esto.

Sería bueno, ¿no? Pero, simplemente no puedes hacer eso. Probablemente puedas lograr algo similar escribiendo tus propios “operadores”.

 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 OPERATORS = new HashMap(); static { OPERATORS.put("+",ADDITION); } public String Calculate(String operator, Double operand1, Double operand2) { return String.valueOf(OPERATORS.get(operator).calculate(operand1,operand2); } } 

Obtienes la imagen de cómo extender esto a muchos otros operadores … y no solo a Dobles obviamente. La ventaja de mi método es que puedes mantener tu firma de método aceptando un operador String .

Los operadores, AFAIK, no se pueden pasar como un parámetro en ningún idioma (al menos eso he encontrado).

La razón es que solo los valores (ya sea por copia o por referencia) se pueden pasar como “valores a parámetros”.

Y los operadores no representan valores.