为什么ArrayLists的ArrayList不是多维的?

Lok*_*esh 34 java arrays list arraylist multidimensional-array

我最近出现在面试中,面试官问我一个关于Arrays和的问题ArrayList.

他问我,如果一个数组的数组可以是多维的,那么,为什么是ArrayListArrayList"不是多维?

例如:

// Multidimensional
int[][] array = new int[m][n]; 

// Not multidimensional
ArrayList<ArrayList<Integer>> seq = new ArrayList<ArrayList<Integer>>(); 
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我理解这个吗?

Ous*_* D. 24

Cay S. Horstmann在他的书" 核心Java"中表示不耐烦:

Java中没有二维数组列表,但您可以声明类型变量ArrayList<ArrayList<Integer>>并自行构建行.

由于ArrayLists可以扩展和缩小并变成锯齿而不是多维的事实,可以说它不是一个二维数组,多维意味着固定的行和列,因此我也在注释中说明了Java没有真正的多维数组,但这超出了你的问题的范围.

如果你很好奇为什么我说Java没有真正的多维数组,那么读一下多维数组和C#中的数组数组之间的差异?


只是为了让我回答有关的Java是否有更清晰真实的多维数组或者不是,我也不会说Java没有多维数组,我说的Java没有真正的多维数组和期望JLS有声明:

多维数组不需要在每个级别具有相同长度的数组.

  • 具有不同长度的子阵列不是令人兴奋的部分.更有趣的是,多维数组是一个引用数组,可能是"null"或指向同一个数组.在`Object [] [] ...`的情况下,数组甚至可以包含对自身的引用. (3认同)

Pet*_*ham 13

出于同样的原因,我把所有备用购物袋放入的购物袋不是一个多维购物袋.

如果我把一个坚果放在一个袋子里,然后将那个袋子放在另一个袋子里,我必须进行两次操作才能得到坚果.

如果我将螺母放入二维组件托盘中,我可以使用两个索引执行一个操作来访问它:

组件托盘 资源

类似地,列表列表(或数组数组)与真正的二维数组之间存在根本区别 - 采用两个索引的单个操作用于访问二维数组中的元素,两个操作各自采用一个索引用于访问列表列表中的元素.

ArrayList具有单个索引,因此它具有等级1.二维数组具有两个索引,其等级为2.

注意:'二维数组'我不是指数组(引用)的Java数组,而是指其他语言(如FORTRAN)中的二维数组.Java没有多维数组.如果你的访问者专门提到Java'数组数组'那么我会不同意它们,因为Java int[][]定义了一个对整数数组的引用数组,并且需要两个解引用操作来访问这些元素.例如,C中的数组数组支持使用单个解除引用操作进行访问,因此更接近于多维情况.

  • 你在哪个地方声明`array [index1] [index2]`是一个单独的操作,但`list.get(index1).get(index2)`是两个?在任何一种情况下,我都可以将它分成两个操作,例如`tmp = array [index1]; 结果= TMP [索引2];`... (9认同)

Gho*_*ica 11

从另一方面看:它可以像"多维"数组一样使用列表.您只需要更换array[row][column]someList.get(row).get(column)!

最后,java数组以类似的方式实现:两个dim矩阵也只是一个dim数组的一个暗淡数组!换句话说:差异在表面上更多,而不是根深蒂固的概念原因!

而且要非常精确:Java类型系统允许你Object[][]在这个意义上放下它,它知道那种类型Object[][]; 但正如所说,实际上,没有多维数组; 因为Java看到"两个昏暗"的东西作为数组的引用数组!

另一方面:有一个"多维数组"的概念,例如JVM规范明确提到:

multianewarray指令的第一个操作数是要创建的数组类类型的运行时常量池索引.第二个是实际创建的数组类型的维数.multianewarray指令可用于创建类型的所有维度,如create3DArray的代码所示.请注意,多维数组只是一个对象,因此分别由aload_1和areturn指令加载和返回.


Jac*_* G. 11

我将在这里站出来回答这个问题,但是对于这个广泛的问题没有正确的答案.

我们首先要问,是什么使数组成为多维的?

我将假设你的面试官考虑一个具有固定大小的多维数组(如你在问题中所示),它不能被认为是"锯齿状".根据微软的说法,C#中的锯齿状数组如下:

锯齿状阵列的元素可以具有不同的尺寸和大小.

在Java中,多维数组只是一个数组,其中每个元素也是一个数组.必须使用固定大小定义这些数组,以便在其中索引元素,但如上所述,锯齿状数组可以具有不同的大小.

An ArrayList由数组支持; 但是,当向其添加一定数量的元素时,数组会扩展.由于这个原因,它ArrayList可能变得锯齿状,并且可能被认为不再是多维的.

编辑:重读几遍后,我确信你的面试官只是想让你迷惑.老实说,一种数据类型(数组)是多维的,另一种数据类型(ArrayList使用数组)不是多维的.


Boa*_*ann 11

面试官的说法是荒谬的.

正如您在本页中看到的那样,人们可以争辩说,Java没有真正的多维数组,在这种情况下,它也没有多维数组列表.另一方面,它当然允许您以相同的方式通过数组和ArrayLists表示多维结构.

定义两者之间的主要区别是相当武断和毫无意义的.

可能面试官只是试图开始技术辩论,以测试你解释细节的能力.