2

我有一些包含很多计算内容的函数。所有计算均使用运算符 []、*、/、+ 和 - 完成。Eyerything else 是循环和测试。因此,这些相同的功能“可以”用于实现这些运算符的任何类型,例如。double、float、int、long 等。出于性能原因,我只使用基本类型。有没有办法做到这一点?

另外 - 出于性能原因,我不想将浮点数和整数转换为 double 并以 double 计算。我想在 int 上计算 int,在 float 上计算 float,在 double 上计算 double。我只是不想写 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-call。

java有没有办法做一些事情,比如 <T implements +, implements ->......?

4

4 回答 4

2

你给出的定义方法的建议staticAdd并不像你最初想象的那么糟糕。HotSpot 将为您做的一件事(当它心情好的时候)是内联代码。如果你为你关心的类型定义这样的函数,你很可能会得到不错的性能。

也就是说,您仍将处理自动装箱,因为您无法泛化基元上的方法。如果性能真的那么关键,您可能会陷入编写多个方法签名的困境。不过考虑一下,有传言说原语可能会在 Java/JVM 的未来版本中完全消失。当然,处理包装类型的惩罚不是零,但在许多应用程序中它几乎可以忽略不计。

于 2013-03-27T02:22:21.977 回答
1

Java 支持的唯一运算符重载是+stringify 和 concatenate。如果你想要这个,你想要一种非 Java JVM 语言。

但是,回想一下那个老笑话:“如果你想要 LISP,你就知道在哪里可以找到它。”</p>

于 2013-03-27T02:16:34.577 回答
1

简单地说,这是不可能的。Java 是静态类型的,操作不能从底层类型中抽象出来。

例如,您不能在 Number 上定义算术运算以抽象出底层类型(Short、Integer 等)。

于 2013-03-27T02:18:55.877 回答
1

简短的回答NO,没有办法做到这一点。类型系统不够强大,无法在 Java 中表达这种东西。

此外,由于泛型不支持原始数据类型,您可能必须使用包装类等IntegersFloat使用 Wrapper 类完成的最黑客方法如下,

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);
于 2013-03-27T02:35:03.360 回答