下面的类模拟了一个通用矩阵,可以填充Ts,其中。
public class GenMatrix<T extends Number> {
//local matrix
T[][] matrix;
public GenMatrix(T[][] matrix) {
//if matrix is n x n, set it as local
if (matrix.length == matrix[0].length)
this.matrix = matrix;
}
//multiplies the matrix with a vector of the same type T and returns a Double vector
Double[] multVector (T[] vector){
//check wether the matrix can be multiplied with the vector
if (vector.length != matrix.length) return null;
//new Double vector
Double[] result = new Double[matrix.length];
//matrix - vector -multiplication
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
//cast all Ts into Doubles
result[j] += ((Double)matrix[i][j])*((Double)vector[j]);
}
}
return result;
}
}
正如您所看到的,方法multVector(..)返回Double []。 我的问题:为什么它不能返回T []?如果我不将计算中的矩阵和向量条目转换为Double,编译器会说“操作符”*“对于类型T是未知的”。我想知道,因为T扩展数字和数字是一个可计算的(不是吗?)。 我不是在寻找一个解决方法来返回一个T []向量,而是为了回答“为什么它不起作用”-question。
关心Tak3r07
答案 0 :(得分:0)
当某些内容延伸Number
时,您无法将其转换为Double
,Integer
或任何其他子类。阅读Java中原语和Object数据类型之间的区别。数字运算符仅适用于基元类型。将演员表应用到Double
并使用*
时会发生什么情况,Java会执行一个名为自动取消装箱的过程。
你的演员阵容可能会遇到ClasscastException
。而不是这个
result[j] += ((Double)matrix[i][j])*((Double)vector[j]);
这样做:
result[j] += (matrix[i][j].doubleValue())*(vector[j].doubleValue());
答案 1 :(得分:0)
未为Number
定义数学运算符。它们是为数字基元定义的:byte
,short
,int
,long
。您可以说:
Integer i = 5;
int j = i + 2;
autoboxing 会自动将i
替换为i.intValue()
在i + 2
中的表达式+
。
这就是您不能将T
运算符与泛型multVector()
一起使用的原因。
方法. To do this you should pass your definition of
可以返回泛型类型:T [] multVector(T [] input)interface MathOperator<T> {
perform(T one, T two);
}
class MultiplyDouble implements MathOperator<Double> {
perform(Double one, Double two) {
return one * two;
}
}
T[] multVector (T[] vector, MathOperator<T> operator){...}
*`到方法:
multVector (new Double[] {1.1, 2.2, 3.3}, new MultiplyDouble());
现在您可以按以下方式调用此方法:
java.lang.reflect.Array
BTW创建通用阵列的实例也是挑战。提示:用户类{{1}}。
答案 2 :(得分:0)
multVector
当然可以返回一个T数组。问题是:
Number
类对于第一部分,你必须知道T代表的实际类。所以你应该:
...
T[][] matrix;
Class<T> clazz;
public GenMatrix(T[][] matrix, Class<T> clazz) {
//if matrix is n x n, set it as local
if (matrix.length == matrix[0].length)
this.matrix = matrix;
this.clazz = clazz;
}
...
T[] result = (T[]) Array.newInstance(clazz, matrix.length);
...
对于第二种情况,你可以继续对double进行计算并在最后进行投射:
abstract <T> fromDouble(double value); // to be implemented in actual class
//matrix - vector -multiplication
double res;
for (int j = 0; i < matrix.length; i++) {
res = 0.;
for (int i = 0; j < matrix[0].length; j++) {
//cast all Ts into Doubles
res += matrix[i][j].doubleValue() * vector[j].doubleValue();
}
resul[j] = fromDouble(res);
}
如你所见,有限的收益要复杂得多。