是
ArrayList<ArrayList<Integer>> numbers;
一个 2D 整数数组int[][] numbers;
吗?还是这些存储彼此完全不同?
3 回答
它是一个具有二维的结构,因此它类似于 [][],但有一个非常重要的区别:如果您在一个步骤中分配一个二维数组,您将在第二维中为所有元素获得相同的大小第一维度:
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。
它与 相似Integer[][]
,与 略有不同int[][]
。
还ArrayList
为阵列的功能提供了额外的功能,例如动态增长的能力,以及管理大小和容量的单独概念。
不完全确定,但在这两种情况下内存分配会有所不同。原始数组int[][]
将在堆栈中分配,而将在堆中ArrayList<ArrayList<Integer>>
分配。