Predefining multiplication for generics in java

末鹿安然 提交于 2019-12-11 03:23:26

问题


So I'm trying, for all intents and purposes, to realize for myself a java version of C++'s STL algorithm inner_product for vector parameters. So far, my code(which is probably fundamentally wrong) looks like this:

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;
}

The problem is that the operator * is undefined for the types T, K. However my knowledge so far doesn't cover predefining operators, though as far as I know it's not possible in Java as well. Any help would be appreciated in the way of realizing the function to take generics. Thanks in advance.


回答1:


There is no nice way to do this, for two reasons:

  1. Type parameters (T, K) must refer to object types, not primitives.
  2. Java does not have operator overloading.

The closest you can get is something like this (modulo syntax errors, my generics are rusty):

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;
}

This will work for the object wrappers around primitive types, i.e. Double but not double, etc.

Also, like your version, this returns double no matter what type was passed in. And because of type erasure, this is pretty hard to fix.




回答2:


T must have a method defined like mutliply so you can call it with a 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;
}

IMHO Vector superseded by List in the Java 1.2 Collections libraries in 1998. Using List may be a better choice.

Do you really need it to be generic? I would just use double

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;
}

or for efficiency use double[] or 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;
}



回答3:


There is no operator overloading in Java, and the multiplication operator only applied to numeric primitive types. If you need to do this on generic types, you'll have to make them implement them an interface which allows transforming them into doubles:

public interface DoubleProvider
    double getDouble();
}

And then, you can define the following method:

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;
}

Notice how my code

  • respects the Java naming conventions
  • acepts any kind of Iterable, rather than just the obsolete Vector (which should not be used anymore since Java 1.2)


来源:https://stackoverflow.com/questions/10468853/predefining-multiplication-for-generics-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!