Java:“实现运营商?”

时间:2013-03-27 02:09:47

标签: java generics operators

我有一些包含很多计算内容的函数。所有计算都使用运算符[],*,/,+和 - 来完成。 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 -> ......?

4 个答案:

答案 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不支持原始数据类型,您可能必须使用包装类,如IntegersFloat等。使用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);