我正在研究我的数据结构技巧。我在网上找到了一本很棒的免费书籍Open Data Structures in Java.在阅读之后,我试图用所提供的代码创建所有声明的数据结构,这样我就可以将它们灌输到我的记忆中。
我遇到了“错误”,在我的生活中我无法弄明白:在resize()
的{{1}}方法(第2.1.2节)中,有代码行 - ArrayStack
。关键在于包含元素的数组既不太小也不太大。如果我使用这行代码,我会从Eclipse获得以下错误消息:
T[] b = newArray(Math.max(n*2,1));
所以,我认为它一定是“拼写错误”,其意思是“新数组”。但是修复它会让我看到Eclipse的以下错误消息:
The method newArray(int) is undefined for the type ArrayStack<T>.
。
我不明白我错过了什么或做错了什么。 总结一下我的问题,如何声明和实例化一个新的通用数组,特别是在固定大小的情况下?
答案 0 :(得分:2)
鉴于T
的等级,我们称之为klass
...
对于长度为n
的一维数组:
T[] arr = (T[]) Array.newInstance(klass, n)
对于长度为n x m
的二维数组:
T[][] 2dArr = (T[][]) Array.newInstance(klass, n, m)
以上实际上是两个不同的函数,一个采用int
参数,第二个采用int...
参数,您也可以将其作为数组传递。两者都返回Object
,你需要一个未经检查的演员。
如果你想要一个长度为n
的锯齿状数组,第二维未定,你必须得到T[]
的类,让我们称它为klass2
,然后再做
T[][] 2dArr2 = (T[][]) Array.newInstance(klass2, n)
这就是为什么你还需要将一个类型传递给collection.toArray(T[] arr)
,否则你会得到一个Object[]
的vanilla toArray()
方法,因为它不知道类型。
答案 1 :(得分:1)
您想要的是:
void resize() {
T[] b = new T[Math.max(n*2,1)];
for (int i = 0; i < n; i++) {
b[i] = a[i];
}
a = b;
}
但这不起作用,因为T在运行时实际上并不知道,而且必须如此。但是,这可以使用通用安全构造函数编写。
void resize() {
T[] b = (T[]) Array.newInstance( a.getClass().getComponentType(),
Math.max(n*2,1) );
for (int i = 0; i < n; i++) {
b[i] = a[i];
}
a = b;
}
似乎作者意味着在该类中有一个方法newArray:
void T[] newArray(int size) {
return (T[]) Array.newInstance( a.getClass().getComponentType(), size);
}
答案 2 :(得分:0)
Java并不是一件容易的事。由于type erasure T的类在运行时不可用(当您需要确定要创建的数组类型时)。
但是,由于您已经有一个数组(a
),因此您可以使用反射来创建该类型的新数组。
看起来像这样:
import java.lang.reflect.Array;
public class Test {
public static void main(String args[]) throws Exception {
Object array[] = new Object[5];
array = resizeArray(array, 10);
for (Object o : array) {
System.out.println(o);
}
}
public static <T>
T[] resizeArray(T[] a, int newSize) throws Exception {
T[] b = (T[]) Array.newInstance(a.getClass().getComponentType(),
newSize);
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
return b;
}
}