我有一个矩阵类,它接收一个范型对象,其扩展了Number类型。
例如:
public class Matrix<T extends Number>
我想要比较两个具有相同值的矩阵:
Matrix:
row=[0] 273 455
row=[1] 243 235
row=[2] 244 205
row=[3] 102 160
并且
Matrix:
row=[0] 273 455
row=[1] 243 235
row=[2] 244 205
row=[3] 102 160
在Matrix类中,我有一个equals方法,它看起来像这样:
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof Matrix))
return false;
Matrix<T> m = (Matrix<T>) obj;
if (this.rows != m.rows)
return false;
if (this.cols != m.cols)
return false;
for (int i=0; i<matrix.length; i++) {
T t1 = matrix[i];
T t2 = m.matrix[i];
if (!t1.equals(t2))
return false;
}
return true;
}
这一行出现了错误:
t1.equals(t2)
即使两个数相等,也会显示不同。例如:"273"和"273"。
当我调试equals方法时,它失败了,因为它假定数字是Long类型的:
这来自于Java SDK Long.class:
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
基本上,它失败是因为obj不是Long的实例。
我可以轻松地更改我的equals方法如下:
if (t1.longValue()!=t2.longValue())
return false;
但是我想知道在这种情况下检查相等的正确方法是什么,以及为什么泛型T上的equals方法假定它是Long。
编辑:
我的测试代码定义了“整数矩阵泛型类型”,这使得相等性测试(使用Long进行比较)对我来说很奇怪。
测试代码:
Matrix<Integer> matrix1 = new Matrix<Integer>(4, 3);
matrix1.set(0, 0, 14);
matrix1.set(0, 1, 9);
matrix1.set(0, 2, 3);
matrix1.set(1, 0, 2);
matrix1.set(1, 1, 11);
matrix1.set(1, 2, 15);
matrix1.set(2, 0, 0);
matrix1.set(2, 1, 12);
matrix1.set(2, 2, 17);
matrix1.set(3, 0, 5);
matrix1.set(3, 1, 2);
matrix1.set(3, 2, 3);
Matrix<Integer> matrix2 = new Matrix<Integer>(3, 2);
matrix2.set(0, 0, 12);
matrix2.set(0, 1, 25);
matrix2.set(1, 0, 9);
matrix2.set(1, 1, 10);
matrix2.set(2, 0, 8);
matrix2.set(2, 1, 5);
Matrix<Integer> result1 = new Matrix<Integer>(4,2);
result1.set(0, 0, 273);
result1.set(0, 1, 455);
result1.set(1, 0, 243);
result1.set(1, 1, 235);
result1.set(2, 0, 244);
result1.set(2, 1, 205);
result1.set(3, 0, 102);
result1.set(3, 1, 160);
Matrix<Integer> matrix3 = matrix1.multiply(matrix2);
if (!matrix3.equals(result1)) {
System.err.println("Matrix multiplication error. matrix3="+matrix3+" result1"+result1);
return false;
}
这里是矩阵代码的链接,但没有定义equals()方法。我还没有检查equals()方法的代码。
Long.equals
只能与另一个Long
相等,似乎存在缺陷,而且没有一个相等函数可以将其与任何Number
(或至少是 JDK 提供的已知Number
类)进行比较。不幸的是,在 Apache Commons 中我也没有看到这样的相等函数。 - ajbMatrix<T>
对象的声明。它们都是Matrix<Long>
吗?如果是,比较应该可以工作。我强烈怀疑您有两个具有不同类型的T
的Matrix<T>
对象。如果是这种情况,那么比较将失败,因为它将使用Object#equals()
进行比较。关键在于Number
没有自己的equals()
方法,因为它无法知道如何将两个任意数字强制转换为支持比较的形式。 - Jim GarrisonMatrix<Integer>
的情况下使用Long
进行比较的问题:我认为我们需要看一下matrix
成员是如何声明的,它在构造函数中是如何赋值的,以及可能是set
方法的具体实现。你代码中的某些部分可能会导致编译器创建一个Long
来存储matrix[i]
中的某个i
。 - ajb