3

ArrayList<ArrayList<Integer>> numbers;一个 2D 整数数组int[][] numbers;吗?还是这些存储彼此完全不同?

4

3 回答 3

7

它是一个具有二维的结构,因此它类似于 [][],但有一个非常重要的区别:如果您在一个步骤中分配一个二维数组,您将在第二维中为所有元素获得相同的大小第一维度:

int[][] arrayOfInts = new int[5][4];

for (int[] second : arrayOfInts) {
   System.out.println(second.length);
}

打印 5 次“4”。

使用 ArrayList 的 ArrayList 的所有第二维元素可能具有不同的大小。

正如 jlordo 所指出的:如果动态创建整数数组,则它也可能具有不同长度的第二维:

int[][] anotherArray = new int[5][];

for (int i=0; i<5; i++) {
  anotherArray[i] = new int[i];
}

在这种情况下,如果在初始化之前访问了第二维,则可以抛出 NullPointerException,例如:

int[][] yetAnotherArray = new int[5][];
System.out.println(yetAnotherArray[2][3]);

另一个区别:在分配一个 int[x][y] 之后,它在两个维度中的所有元素的内存都是从一开始就分配的。在 ArrayList 的 ArrayList 中,分配了列表所需的内存,但在创建其内容之前不会使用其元素所需的内存。因此,与之前类似的代码不会打印任何内容,因为一开始第一个 ArrayList 中甚至不会有一个元素。

为了获得第二维,您首先必须创建第二维的所有 ArrayList:

ArrayList<ArrayList<Integer>> arrayOfArrays = new ArrayList<ArrayList<Integer>>();
for (int i=0; i < 5; i++) {
    arrayOfArrays.add(new ArrayList<Integer>();
}

进一步在访问方面:

int[][] arrayOfInts = new int[5][4];
System.out.println(arrayOfInts[2][3]);

打印 0 因为所有内存都已分配。该访问在寻址维度及其值方面都是安全的,因为它是原始类型。

ArrayList<ArrayList<Integer>> arrayOfArrays = new ArrayList<ArrayList<Integer>>();
for (int i=0; i < 5; i++) {
    arrayOfArrays.add(new ArrayList<Integer>();
}
System.out.println(first.get(2).get(3));

抛出 ArrayOutOfBoundsException。您必须在访问元素之前检查它们的大小。

现在 int[][] 和 Integer[][] 之间还有一个重要区别:原始类型总是有值,因此在分配 int[4][5]之后,单元化元素的值为 0。Integer[4][5] 包含对象,因此未初始化的元素将改为null

于 2012-11-30T08:12:23.203 回答
3

它与 相似Integer[][],与 略有不同int[][]

ArrayList为阵列的功能提供了额外的功能,例如动态增长的能力,以及管理大小容量的单独概念。

于 2012-11-30T08:03:07.093 回答
1

不完全确定,但在这两种情况下内存分配会有所不同。原始数组int[][]将在堆栈中分配,而将在堆中ArrayList<ArrayList<Integer>>分配。

于 2012-11-30T08:12:06.463 回答