我正在编写一种将树中每个节点的数据大小加倍的方法。我想我已经编写了算法来编写它,但是我无法弄清楚如何将泛型类型乘以 2。
所以基本上我想获取一个 T 类型的数据并将其转换为整数,将其乘以 2,然后将其存储为 T 类型。我尝试了一些选项,但没有一个有效。关于我应该如何做到这一点的任何帮助都会有所帮助。如果您需要任何其他信息,请告诉我。谢谢。
由于类型擦除,您不能直接执行此操作。一种方法是为“知道”如何加倍自身的对象定义一个通用接口:
public interface Doubler<T> {
T doubled(T arg);
}
然后你可以让每个节点(知道如何加倍自己)实现Doubler
接口。
还有其他方法(工厂方法、工厂对象、传递Class<T>
实例等)可能同样有效(或更好)。但是你不能做的一件事是在只知道泛型类型的代码中创建一个泛型类型的实例,而不是别的。
当你声明你的泛型类/树实例/泛型方法时,不要让泛型类型参数 T 完全不受约束,而是让它成为一个数字(Long 或 Double,取决于你是否需要处理整数或浮点数:
代替:
public class DoubleTree<T> {
private TreeSet<T> myTree;
public void doubleTree() {
// ...
for (T treeElement: myTree) {
// no way to double element because
// "minimum guaranteed base type of T" is Object!!
}
}
}
在第一行尝试T extends Long
作为泛型类型参数:
public class DoubleTree<T extends Long> {
private TreeSet<T> myTree;
public void doubleTree() {
// ...
for (T treeElement: myTree) {
// Element has the Long interface - guaranteed
T doubleIt = 2 * treeElement;
// Note - you should really prevent numerical overflow in the above
// e.g. if (treeElement < Long.MAX_VALUE / 2) {
// T doubleIt = 2 * treeElement;
// } else { // Overflow error }
}
}
}
为了更通用,您可以使用“数字”而不是“长”。但是 Number 是一种抽象类型,它不直接支持常量乘法!您可以通过以下方式在运行时检查实际类来解决此问题instanceof
:
if (treeElement instanceof Long) {
Long doubleIt = 2 * treeElement.longValue();
} else if (treeElement instanceof Integer) {
Integer doubleIt = 2 * treeElement.intValue();
} else if (treeElement isntanceof Float) {
Float doubleIt = 2.0 * treeElement.floatValue();
} // ..... etc