我有一些包含很多计算内容的函数。所有计算都使用运算符[],*,/,+和 - 来完成。 Eyerything是循环和测试。因此,这些相同的功能“可以”用于实现这些运算符的任何类型,例如。 double,float,int,long等。出于性能原因,我只使用基本类型。有没有办法做这个通用的?
另外 - 出于性能原因,我不想将浮点数和整数转换成双倍和计算加倍。我想在int上int,在浮点数上浮点数和在双精度数上双重计算。我只是不想写相同代码的3倍,只是使用的类型不同。
例如,猜猜你有
public double doSomething(double a, double b)
{
return a * b + 1;
}
当然,实际的fn比这更多。
我认为诀窍就像是
public T doSomething(T a, T b)
{
return staticAdd(staticMul(a,b),1);
}
...并将基本操作定义为所有使用类型的静态fn。但由于没有内联,这将增加另一个fn调用。
java中是否有办法做某些事情
<T implements +, implements ->
......?
答案 0 :(得分:2)
您为定义staticAdd
等方法所提出的建议并不像您最初想的那么糟糕。 HotSpot将为您做的事情之一(当它处于心情时)是inline code。如果你为你所关注的类型定义这样的函数,你可能会获得不错的表现。
那就是说,你仍然要处理自动装箱,因为你不能对基元的方法进行泛化。如果性能真的非常重要,那么您可能会遇到写多个方法签名的问题。 但是,请考虑一下,有传言说Java / JVM的未来版本中的原语可能go away entirely。当然,处理包装类型的处罚不是零,但在许多应用程序中它的接近程度可以忽略不计。
答案 1 :(得分:1)
唯一重载Java支持的运算符是+
stringify和concatenate。如果需要,可以使用其中一种非Java JVM语言。
但是,回想一下这个老笑话:“如果你想要LISP,你知道在哪里找到它。”
答案 2 :(得分:1)
简单地说,这是不可能的。 Java是静态类型的,操作不能从底层类型中抽象出来。
例如,您不能在Number上定义算术运算,以抽象出基础类型(Short,Integer等)。
答案 3 :(得分:1)
简短回答否,没有办法做到这一点。类型系统不够强大,不能用Java表达这种东西。
此外,由于Generics不支持原始数据类型,您可能必须使用包装类,如Integers
,Float
等。使用Wrapper类完成Hackiest的方法如下,
public class Calculator<T extends Number> {
T add(T a, T b) {
if (a instanceof Double) {
return (T) Double.valueOf((a.doubleValue() + b.doubleValue()));
} else if (a instanceof Float) {
return (T) Float.valueOf(((a.floatValue() + b.floatValue())));
} else if (a instanceof Integer) {
return (T) Integer.valueOf(((a.intValue() + b.intValue())));
}
throw new IllegalArgumentException();
}
}
您可以拨打以下相同的内容。
Calculator<Double> c1 = new Calculator<Double>();
mc.add(1.0, 1.1);
Calculator<Integer> c1 = new Calculator<Integer>();
mc.add(1, 2);