2

因此,出于所有意图和目的,我正在尝试为自己实现一个用于矢量参数的 C++ 的 STL 算法 inner_product 的 Java 版本。到目前为止,我的代码(可能根本上是错误的)看起来像这样:

public static<T,K> double inner_product(Vector<T> v1, Vector<K> v2)
{
    double isum = 0;
    for(int i=0;i<v1.size()&&i<v2.size();i++)
    {
        isum+=v1.elementAt(i)*v2.elementAt(i);
    }

    return isum;
}

问题是运算符 * 对于类型 T、K 是未定义的。但是,到目前为止,我的知识还没有涵盖预定义运算符,尽管据我所知,这在 Java 中也是不可能的。在实现采用泛型的功能的方式上,我们将不胜感激。提前致谢。

4

3 回答 3

3

没有很好的方法可以做到这一点,原因有两个:

  1. 类型参数 ( T, K) 必须引用对象类型,而不是原始类型。
  2. Java 没有运算符重载。

你能得到的最接近的是这样的(模语法错误,我的泛型生锈了):

public static<T extends Number,K extends Number> double inner_product(Vector<T> v1, Vector<K> v2)
{
    double isum = 0;
    for(int i=0;i<v1.size()&&i<v2.size();i++)
    {
        isum+=v1.elementAt(i).doubleValue()*v2.elementAt(i).doubleValue();
    }

    return isum;
}

这将适用于围绕原始类型的对象包装器,即Double但不是double等。

此外,就像您的版本一样,double无论传入什么类型,它都会返回。而且由于类型擦除,这很难修复。

于 2012-05-06T07:23:26.297 回答
2

T 必须定义一个方法,mutliply这样你就可以用 V 调用它

interface T {
    double multiply(V v);
}

public static<T,K> double inner_product(Vector<T> v1, Vector<K> v2) {
    double isum = 0;
    for(int i=0; i<v1.size() && i<v2.size(); i++) {
        isum += v1.elementAt(i).multiply(v2.elementAt(i));
    }
    return isum;
}

恕我直言 Vector 在 1998 年被 Java 1.2 Collections 库中的 List 取代。使用 List 可能是更好的选择。

你真的需要它是通用的吗?我会用双

public static double inner_product(List<Double> v1, List<Double> v2) {
    double isum = 0;
    for(int i=0; i<v1.size() && i<v2.size(); i++) 
        isum += v1.get(i) * v2.get(i);

    return isum;
}

或为了提高效率使用 double[] 或 TDoubleArrayList

public static double inner_product(double[] v1, double[] v2) {
    double isum = 0;
    for(int i=0; i<v1.size() && i<v2.size(); i++) 
        isum += v1[i] * v2[i];

    return isum;
}
于 2012-05-06T07:19:24.220 回答
1

Java 中没有运算符重载,乘法运算符仅适用于数字基本类型。如果您需要对泛型类型执行此操作,则必须使它们实现一个接口,该接口允许将它们转换为双精度:

public interface DoubleProvider
    double getDouble();
}

然后,您可以定义以下方法:

public static <T extends DoubleProvider, K extends DoubleProvider> double innerProduct(Iterable<T> v1, Iterable<K> v2) {
    Iterator<T> it1 = v1.iterator();
    Iterator<K> it2 = v2.iterator();
    double sum = 0D;
    while (it1.hasNext() && it2.hasNext()) {
        T t = it1.next();
        K k = it2.next();
        sum += t.getDouble() * k.getDouble();
    }
    return sum;
}

注意我的代码

  • 尊重 Java 命名约定
  • 接受任何类型的 Iterable,而不仅仅是过时的 Vector(自 Java 1.2 起不应再使用)
于 2012-05-06T07:25:14.370 回答