问题
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:
- Type parameters (
T,K) must refer to object types, not primitives. - 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