Cómo hacer una lambda genérica que compare cualquier número de tipo idéntico.
Tengo la necesidad de reemplazar un operador de comparación en tiempo de ejecución, donde se compararían dos Números mediante GreaterThanOrEquals, LessThanOrEquals, Equals, etc. Pero idealmente no quiero replicar mi código para Integers, Doubles, Longs, Shorts, Floats y Bytes. Una parte de mis requisitos es mantener la operación en lambdas tanto como sea posible para mejorar el rendimiento.
Nota: Ambos valores siempre serán del mismo tipo. No tengo intención de hacer comparaciones de tipos mixtos.
Aquí hay un borrador de mi código. Intenté simplemente parametrizar el último método estático con Java.lang.Number, pero >= no funcionará en Number:
public class Expression {
public Param p1;
public Operator o;
public Param p2;
public Object eval() {
return o.eval(p1.getValue(),p2.getValue());
}
}
public interface Operator
Object eval(T p1,T p2);
}
public interface GreaterOrEqual extends Operator
static Operator
return (v1, v2) -> v1 >= v2;
}
static Operator<double> Doubles() {
return (v1, v2) -> v1 >= v2;
}
static Operator<long> Longs() {
return (v1, v2) -> v1 >= v2;
}
static Operator<number> generic() {
// este no se compilará ya que "> =" no se puede aplicar a Java.lang.Number
return (v1, v2) -> v1 >= v2;
}
}
Editar: Esta duplicación de código también significa que mi código de interfaz gráfica de usuario necesitará usar un “if (Param.value instanceof Integer) Expression.setOperator(GreaterOrEqual.Integers);” lo cual implica aún más duplicación de código.
davy.ai
Para evitar la duplicación de código y mantener la operación en las lambdas tanto como sea posible para mejorar el rendimiento, puede usar los genéricos comodín de Java para definir una sola interfaz de operador que funcione con todos los subtipos de Number. Así es como puede modificar su código:
En el código anterior, definimos una nueva clase parametrizada
Expression<n extends="" number="">
que toma un parámetro de tipoN
que representa el subtipo deNumber
con el que la expresión funcionará. También actualizamos la claseParam
para que sea parametrizada conN
.También definimos un nuevo enum
Comparison
que contiene los diferentes tipos de comparación que queremos admitir. Cada valor de enum anula el métodogetOperator
para devolver el operador correspondiente para ese tipo de comparación.Finalmente, actualizamos la interfaz
Operator
para que también sea parametrizada conN
, y modificamos las lambdas en el enumComparison
para usardoubleValue()
en lugar de los operadores>=
y<=
para poder comparar cualquier subtipo deNumber
.Con este nuevo diseño, puede crear expresiones para cualquier subtipo de
Number
simplemente instanciando la claseExpression<n>
con el parámetro de tipo deseado, y pasándole instancias correspondientes deParam<n>
yComparison
. Ya no necesitas duplicar código o escribir declaraciones if para verificar el tipo de los parámetros.