[英]Java/P5: How to declare an Array of Arraylists holding FloatLists?
If I can declare an Array of FloatLists: FloatList [][] values = new FloatList[3][3];
如果可以声明一个FloatLists数组: FloatList [][] values = new FloatList[3][3];
Why doesn't it work to declare an Array of ArrayLists holding FloatLists like this: ArrayList<FloatList> [][] values = new ArrayList<FloatList>() [3][3];
为什么这样声明包含FloatList的ArrayList数组不起作用: ArrayList<FloatList> [][] values = new ArrayList<FloatList>() [3][3];
? ? OR EVEN: ArrayList<FloatList> [][] values = new ArrayList<FloatList> [3][3]();
ArrayList<FloatList> [][] values = new ArrayList<FloatList> [3][3]();
: ArrayList<FloatList> [][] values = new ArrayList<FloatList> [3][3]();
How can this be achieved? 如何做到这一点? Will it be hard to refer to the floats
buried deep under its crusty texture? 很难指望floats
在其硬壳质地下的floats
吗?
Work from the inner-most type to the outer-most type. 从最里面的类型到最外面的类型工作。 You start with FloatList
: 您从FloatList
开始:
FloatList
Then wrap that in an ArrayList
: 然后将其包装在ArrayList
:
ArrayList<FloatList>
Then you want an array of that: 然后,您需要一个数组:
ArrayList<FloatList>[]
Or a 2D array: 或二维数组:
ArrayList<FloatList>[][]
That gives you the type for the declaration, but then you have to initialize the variable by giving it a value. 这样就为您提供了声明的类型,但随后您必须通过为变量赋一个值来对其进行初始化。 Start with the array by giving it a size: 通过给数组指定大小来开始:
ArrayList<FloatList>[] array = new ArrayList[10];
This gives you an array of ArrayList<FloatList>
objects, but they start out as null
. 这为您提供了ArrayList<FloatList>
对象的数组,但是它们以null
开头。 To give them a value, you'd loop over every index in the array and use the new
keyword to set the value of the index to an instance of ArrayList<FloatList>
: 为了给它们一个值,您可以遍历数组中的每个索引,并使用new
关键字将索引的值设置为ArrayList<FloatList>
的实例:
for(int i = 0; i < array.length; i++){
array[i] = new ArrayList<FloatList>();
}
For a 2D array, you'd use the same logic, just in a nested for
loop. 对于2D数组,只需在嵌套的for
循环中使用相同的逻辑即可。
Then to add a FloatList
to an ArrayList
at a specific index of the array, you'd do this: 然后将FloatList
添加到ArrayList
的特定索引处的ArrayList
中,您可以这样做:
array[i].add(new FloatList());
Finally, to add a float
to a FloatList
in an ArrayList
at an index in the array, you'd do this: 最后,要将float
添加到ArrayList
中位于数组索引处的FloatList
中,请执行以下操作:
array[x].get(y).append(0.5);
And to get a float
out of an index in the FloatList
in an ArrayList
at an index in the array, you'd do this: 为了从ArrayList
FloatList
中的ArrayList
的FloatList
的索引中获取float
,您可以这样做:
float f = array[x].get(y).get(z);
Putting it all together, it looks like this: 放在一起,看起来像这样:
ArrayList<FloatList>[] array = new ArrayList[10];
for(int i = 0; i < array.length; i++){
array[i] = new ArrayList<FloatList>();
}
array[1].add(new FloatList());
array[1].get(0).append(0.25);
array[1].get(0).append(0.5);
array[1].get(0).append(0.75);
float f = array[1].get(0).get(2);
println(f);
ArrayList<FloatList> [][] values = new ArrayList[3][3];
Basically, you're declaring that you want an object that is a 3D array of ArrayList
s, and not generating actual ArrayList
objects. 基本上,您是在声明要使用ArrayList
的3D数组作为对象,而不是生成实际的ArrayList
对象。
Afterwards, you have to instantiate each of them, so for example: 之后,您必须实例化它们中的每一个,因此例如:
values[0][0] = new ArrayList<>();
And so on. 等等。
It doesn't work because of the way the JVM provides Generics. 由于JVM提供泛型的方式而无法使用。 Generics in Java is a front-end compiler feature that becomes raw type usages and casts at execution time. Java中的泛型是一种前端编译器功能,它成为原始类型的用法并在执行时强制转换。
What is the compiler doing when I use generics? 使用泛型时,编译器在做什么?
Here's a terribly-contrived example. 这是一个非常人为的例子。 Let's say I want to create a List<String>
to store command line arguments that I will later use to kick off a new process with, like so: 假设我要创建一个List<String>
来存储命令行参数,稍后将用它们来启动一个新进程,如下所示:
List<String> cmd = new ArrayList<>();
cmd.add("java");
cmd.add("-jar");
cmd.add("path/to/my.jar");
...
String args = cmd.get(0)+" "+cmd.get(1)+" "+cmd.get(2);
At compile time, the compiler will check to make sure that I am using the String
type every time I use a generic List
method via cmd
and throw an error if I try to use instances of an incompatible type. 在编译时,每次我通过cmd
使用通用List
方法时,编译器都会检查以确保我使用的是String
类型,如果尝试使用不兼容类型的实例,则会引发错误。 However, there's a little thing called erasure that happens during compilation, before execution. 但是,在编译之前,执行之前会发生一些称为擦除的事情。 Effectively, under the hood, the compiler converts the code above into something like this: 实际上,编译器实际上将上面的代码转换为如下代码:
List cmd = new ArrayList();
cmd.add("java");
cmd.add("-jar");
cmd.add("path/to/my.jar");
...
String args = (String)cmd.get(0)+" "+(String)cmd.get(1)+" "+(String)cmd.get(2);
So why doesn't my generic array code compile? 那为什么我的通用数组代码不能编译?
In your example, you wanted to create an array of a generic type, like so: 在您的示例中,您想要创建一个通用类型的数组,如下所示:
ArrayList<FloatList>[][] array = new ArrayList<FloatList>[n][m]; //Doesn't compile? What gives?
The problem is, because of type erasure, the ArrayList<FloatList>
class type doesn't really exist, and now you've asked the JVM to create a 2-dimensional array of that non-existent type. 问题是,由于类型擦除, ArrayList<FloatList>
类类型实际上并不存在,现在您已要求JVM创建该不存在类型的二维数组。
Okay, so what's the alternative? 好吧,那有什么选择呢?
Well ... it isn't pretty, but you could do something like this: 好吧...这并不漂亮,但是您可以执行以下操作:
class ArrayListOfFloatList extends ArrayList<FloatList>{
...
}
//Somewhere else in your code:
ArrayListOfFloatList[][] myArray = new ArrayListOfFloatList[n][m];
//This will compile because ArrayListOfFloatList is a real class.
The only other way around this would be to not use arrays. 解决此问题的唯一其他方法是不使用数组。 Ugly, perhaps, but it's unfortunately a limitation of how Java is currently implemented. 也许很丑,但这很不幸,这是目前Java实现方式的局限性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.