使用泛型在java中实现B树
我已经用java编写了自己的2-3-4树。目前,我的代码如下所示:使用泛型在java中实现B树,java,generics,b-tree,Java,Generics,B Tree,我已经用java编写了自己的2-3-4树。目前,我的代码如下所示: public class tree234{ private class node{ Comparable data[]=new Comparable[3]; node next[]=new node[4]; } } public class tree234<T extends Comparable<? super T>>{
public class tree234{
private class node{
Comparable data[]=new Comparable[3];
node next[]=new node[4];
}
}
public class tree234<T extends Comparable<? super T>>{
private class node{
T[] data=new T[3];//error here!
node[] next=new node[4];
}
}
相反,我想要这样的东西:
public class tree234{
private class node{
Comparable data[]=new Comparable[3];
node next[]=new node[4];
}
}
public class tree234<T extends Comparable<? super T>>{
private class node{
T[] data=new T[3];//error here!
node[] next=new node[4];
}
}
虽然我知道我不能创建数组,也不知道为什么,但我想不出一个合理简单的方法来用泛型实现node类。有什么建议吗?您可以随时进行显式播放 由于T扩展了Comparable,因此变量T[]将在编译类中作为Comparable[]结束。因此数组类型必须是可比较的[]-不能将对象分配给可比较的变量 另一种数组类型是Tree234.Node[]
您始终可以执行显式强制转换 由于T扩展了Comparable,因此变量T[]将在编译类中作为Comparable[]结束。因此数组类型必须是可比较的[]-不能将对象分配给可比较的变量 另一种数组类型是Tree234.Node[]
啊,Java数组和泛型,我多么讨厌你。 虽然使用列表肯定可以解决键入问题,但有时数组的速度确实是必要的 反射当然是一种方法,在这里搜索更多,但我发现代码太臭了,不合我的口味。对于更简单的情况,您可以使用类似我下面介绍的ArrayConstructor接口。如果不是因为节点类型,我们可以在不发出任何警告的情况下解决您的问题,但代价是增加了代码的冗余度和泄漏的抽象,您的类的用户将不得不提供节点和T数组构造函数。不幸的是,由于节点类型也采用类型参数,因此我们无法在没有警告的情况下一般地处理这种情况
interface ArrayConstructor<T> {
T[] constructArray(int size);
}
class Node <T extends Comparable<? super T>>{
private T[] data;
private Node[] next;
Node(ArrayConstructor<T> dataConstructor,
ArrayConstructor<Node<T>> nodeConstructor){
this.data = dataConstructor.constructArray(3);
this.next = nodeConstructor.constructArray(4);
}
}
啊,Java数组和泛型,我多么讨厌你。 虽然使用列表肯定可以解决键入问题,但有时数组的速度确实是必要的 反射当然是一种方法,在这里搜索更多,但我发现代码太臭了,不合我的口味。对于更简单的情况,您可以使用类似我下面介绍的ArrayConstructor接口。如果不是因为节点类型,我们可以在不发出任何警告的情况下解决您的问题,但代价是增加了代码的冗余度和泄漏的抽象,您的类的用户将不得不提供节点和T数组构造函数。不幸的是,由于节点类型也采用类型参数,因此我们无法在没有警告的情况下一般地处理这种情况
interface ArrayConstructor<T> {
T[] constructArray(int size);
}
class Node <T extends Comparable<? super T>>{
private T[] data;
private Node[] next;
Node(ArrayConstructor<T> dataConstructor,
ArrayConstructor<Node<T>> nodeConstructor){
this.data = dataConstructor.constructArray(3);
this.next = nodeConstructor.constructArray(4);
}
}
除了显而易见的方法外,只需使用对象数组并强制转换返回值,还可以使用array.newInstanceclass、size并将返回值强制转换为T[]。您仍然必须抑制警告,因为当前泛型实现无法避免这种情况,但这种方式可以在将对象插入数组时进行类型检查,而不是在访问对象时进行类型检查,并且更早的错误会更好
在背景中使用反射,因此可能不是世界上性能最好的东西。除了显而易见的问题,只需使用对象数组并强制转换返回值,您还可以使用array.newInstanceclass,size并将返回值强制转换为T[]。您仍然必须抑制警告,因为当前泛型实现无法避免这种情况,但这种方式可以在将对象插入数组时进行类型检查,而不是在访问对象时进行类型检查,并且更早的错误会更好 在背景中使用反射,因此可能不是世界上性能最好的东西。您应该创建一个新的可比较的[4]。因为我相信这个数组是您的结构内部的,所以没有人真正关心数组的真正类型 然后,您可以1将其分配给T[]变量(如果您希望确保没有任何外部代码访问它),否则它将崩溃,或者2在取出元素时手动将其强制转换为T。无论哪种方式,您都会收到警告。您应该创建一个新的可比较的[4]。因为我相信这个数组是您的结构内部的,所以没有人真正关心数组的真正类型
interface ArrayConstructor<T> {
T[] constructArray(int size);
}
class Node <T extends Comparable<? super T>>{
private T[] data;
private Node[] next;
Node(ArrayConstructor<T> dataConstructor,
ArrayConstructor<Node<T>> nodeConstructor){
this.data = dataConstructor.constructArray(3);
this.next = nodeConstructor.constructArray(4);
}
}
然后,您可以1将其分配给T[]变量(如果您希望确保没有任何外部代码访问它),否则它将崩溃,或者2在取出元素时手动将其强制转换为T。无论哪种方式,您都会收到警告。您可以使用列表而不是数组吗?@Paul我的代码已经可以使用数组了,更改它会很烦人。不过,如果这是最好的方法,那也是可行的。看看这个问题,你能用列表代替数组吗?@Paul我的代码已经可以处理数组了,修改它会很烦人。但是,如果这是最好的方法,那么它是可行的。检查这个问题我已经尝试过了,但是得到了一个警告,并且不确定该方法是否安全。另外,当我运行一个测试程序时也发生了这种情况:线程主java.lang.ClassCastException中的异常:[Ljava.lang.Object;无法强制转换到[Ljava.lang.Comparable;好的,我修正了两种数组类型都使用裸的非泛型类型,因此不会发生类强制转换异常。我使用eclipse进行测试,没有发现异常
interface ArrayConstructor<T> {
T[] constructArray(int size);
}
class Node <T extends Comparable<? super T>>{
private T[] data;
private Node[] next;
Node(ArrayConstructor<T> dataConstructor,
ArrayConstructor<Node<T>> nodeConstructor){
this.data = dataConstructor.constructArray(3);
this.next = nodeConstructor.constructArray(4);
}
}
警告。如果你得到“未检查”的警告,这些警告可以被忽略或禁止-@suppressWarningunchecked,因为这是安全的。我相信运行时版本和非通用版本一样快,但我没有费心检查字节码…欢迎你。请随意勾选“接受答案”复选框……我已经尝试过了,但得到了一个警告,不确定该方法是否安全。此外,当我运行测试程序时也发生了这种情况:线程主java.lang.ClassCastException中的Exception:[Ljava.lang.Object;无法转换为[Ljava.lang.Comparable;好的,我修正了两种数组类型都使用裸非泛型类型,因此不会发生类强制转换异常。我使用eclipse进行测试,没有收到任何警告。如果您收到“未检查”警告,则可以忽略或禁止这些警告-@suppressWarningUnchecked,因为这是安全的。我相信运行时版本与n一样快在通用版本上,但我没有费心检查字节码…不客气。请随意勾选接受答案复选框…我建议使用新的可比[4],这样在比较键时就不必强制转换。我建议使用新的可比[4],这样在比较键时就不必强制转换。