【问题标题】:Java/P5: How to declare an Array of Arraylists holding FloatLists?Java/P5:如何声明一个包含 FloatLists 的 Arraylists 数组?
【发布时间】:2016-10-27 15:36:55
【问题描述】:

如果我可以声明一个 FloatLists 数组:FloatList [][] values = new FloatList[3][3];

为什么不能像这样声明一个包含 FloatLists 的 ArrayLists 数组:ArrayList<FloatList> [][] values = new ArrayList<FloatList>() [3][3];?甚至:ArrayList<FloatList> [][] values = new ArrayList<FloatList> [3][3]();

如何做到这一点? floats 深埋在它的硬壳质地之下,会不会让人难以指认?

【问题讨论】:

  • ArrayList<FloatList> [][] values = new ArrayList[3][3]; 但是,从概念上讲,这开始变得过于复杂。
  • 我有一个 2D 矩阵,每个正方形中都有未知数量的类别。在类别中保存了一系列值。矩阵完成后,会找到并显示每个类别的中值。
  • 用更多肉的文字更新了它。基本上,您是在实例化一组东西,而不是一堆东西。

标签: java arrays arraylist processing


【解决方案1】:

从最里面的类型到最外面的类型。你从FloatList开始:

FloatList

然后将其包装在 ArrayList:

ArrayList<FloatList>

然后你想要一个数组:

ArrayList<FloatList>[]

或二维数组:

ArrayList<FloatList>[][]

这给了你声明的类型,但是你必须通过给它一个值来初始化变量。从数组开始,给它一个大小:

ArrayList<FloatList>[] array = new ArrayList[10];

这为您提供了一个 ArrayList&lt;FloatList&gt; 对象数组,但它们以 null 开头。要给它们一个值,您需要遍历数组中的每个索引并使用 new 关键字将索引的值设置为 ArrayList&lt;FloatList&gt; 的实例:

for(int i = 0; i < array.length; i++){
   array[i] = new ArrayList<FloatList>();
}

对于二维数组,您可以使用相同的逻辑,只是在嵌套的 for 循环中。

然后在数组的特定索引处将FloatList 添加到ArrayList,您可以这样做:

array[i].add(new FloatList());

最后,要将float 添加到ArrayList 中数组索引处的FloatList,您可以这样做:

array[x].get(y).append(0.5);

要从数组中索引处的ArrayList 中的FloatList 中的索引中获取float,您可以这样做:

float f = array[x].get(y).get(z);

把它们放在一起,它看起来像这样:

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&lt;FloatList&gt;[] array = new ArrayList[10]; 此代码生成Unchecked Warning。没有SuppressWarning("unchecked")有什么办法可以删除
  • @seal 请注意,这是一个处理问题,处理不会为此代码生成任何警告。
【解决方案2】:
ArrayList<FloatList> [][] values = new ArrayList[3][3];

基本上,您是在声明您想要一个由 ArrayLists 组成的 3D 数组的对象,而不是生成实际的 ArrayList 对象。

之后,您必须实例化它们中的每一个,例如:

values[0][0] = new ArrayList<>();

等等。

【讨论】:

    【解决方案3】:

    由于 JVM 提供泛型的方式,它不起作用。 Java 中的泛型是一种前端编译器功能,可在执行时成为原始类型用法和类型转换。

    当我使用泛型时,编译器在做什么?

    这是一个非常人为的例子。假设我想创建一个List&lt;String&gt; 来存储命令行参数,稍后我将使用这些参数来启动一个新进程,如下所示:

    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);
    

    在编译时,编译器会检查以确保每次我通过cmd 使用泛型List 方法时都使用String 类型,如果我尝试使用不兼容的实例,则会抛出错误类型。但是,在编译期间,执行之前,有一个叫做 erasure 的小事情发生。实际上,在引擎盖下,编译器将上面的代码转换成这样的:

    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);
    

    那么为什么我的通用数组代码无法编译?

    在您的示例中,您想创建一个泛型类型的数组,如下所示:

    ArrayList<FloatList>[][] array = new ArrayList<FloatList>[n][m]; //Doesn't compile? What gives?
    

    问题是,由于类型擦除,ArrayList&lt;FloatList&gt; 类类型实际上并不存在,现在您已要求 JVM 创建该不存在类型的二维数组。

    好的,那还有什么替代方法?

    嗯......它并不漂亮,但你可以这样做:

    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.
    

    解决此问题的唯一其他方法是不使用数组。也许丑陋,但不幸的是,它是当前 Java 实现方式的一个限制。

    【讨论】:

    • 我不认为这是正确的。你说的代码不能编译,编译就好了。
    • 您编辑的代码无法编译,因为LinkedList 不是ArrayList 的子类,而不是因为泛型。您绝对必须使用泛型子类才能使用具有数组的泛型。
    • 公平点。我仍然不认为扩展ArrayList 是一个非常合理的解决方案(尤其是在处理上下文中),但否决了撤回。
    • 我完全同意,这就是为什么我说它不漂亮:) 但是你也不想养成忽略编译器警告的习惯。我想这取决于 OP 明智地选择他的毒药;)
    • 另一件值得考虑的事情是,这是 Processing,而不是标准的 Java,所以你的很多语法对于 Processing 开发人员来说是没有意义的。但看起来OP早已不复存在,所以我会离题。感谢您的来回!
    猜你喜欢
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 2012-12-05
    • 2013-09-19
    • 1970-01-01
    • 2019-06-23
    相关资源
    最近更新 更多