简体   繁体   English

Java / P5:如何声明包含FloatLists的Arraylist数组?

[英]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中的ArrayListFloatList的索引中获取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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM